diff --git a/docs/index.md b/docs/index.md
index c2b4da1e..7ceebc6f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -118,6 +118,8 @@ These functions are
[`get_model`](#get-model),
[`reboot`](#reboot),
[`restart_backend`](#restart-backend), and
+[`stop_mining`](#stop-mining), and
+[`resume_mining`](#resume-mining), and
[`send_config`](#send-config).
@@ -202,6 +204,22 @@ These functions are
+### Stop Mining
+::: pyasic.miners.BaseMiner.stop_mining
+ handler: python
+ options:
+ heading_level: 4
+
+
+
+### Resume Mining
+::: pyasic.miners.BaseMiner.resume_mining
+ handler: python
+ options:
+ heading_level: 4
+
+
+
### Send Config
::: pyasic.miners.BaseMiner.send_config
handler: python
diff --git a/pyasic/data/error_codes/__init__.py b/pyasic/data/error_codes/__init__.py
index 219f8f1d..484a0507 100644
--- a/pyasic/data/error_codes/__init__.py
+++ b/pyasic/data/error_codes/__init__.py
@@ -16,3 +16,9 @@ from .whatsminer import WhatsminerError
from .bos import BraiinsOSError
from .X19 import X19Error
from .innosilicon import InnosiliconError
+
+from typing import TypeVar
+
+MinerErrorData = TypeVar(
+ "MinerErrorData", WhatsminerError, BraiinsOSError, X19Error, InnosiliconError
+)
diff --git a/pyasic/miners/_backends/bmminer.py b/pyasic/miners/_backends/bmminer.py
index 392095e5..499d5cd6 100644
--- a/pyasic/miners/_backends/bmminer.py
+++ b/pyasic/miners/_backends/bmminer.py
@@ -14,7 +14,7 @@
import ipaddress
import logging
-from typing import Union
+from typing import Union, List
from pyasic.API.bmminer import BMMinerAPI
@@ -22,6 +22,7 @@ from pyasic.miners.base import BaseMiner
from pyasic.data import MinerData
from pyasic.config import MinerConfig
+from pyasic.data.error_codes import MinerErrorData
from pyasic.settings import PyasicSettings
@@ -169,7 +170,7 @@ class BMMiner(BaseMiner):
async def fault_light_on(self) -> bool:
return False
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
return []
async def get_mac(self) -> str:
@@ -178,6 +179,12 @@ class BMMiner(BaseMiner):
async def restart_backend(self) -> bool:
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def get_data(self) -> MinerData:
"""Get data from the miner.
diff --git a/pyasic/miners/_backends/bosminer.py b/pyasic/miners/_backends/bosminer.py
index 80a2e797..9263a1bf 100644
--- a/pyasic/miners/_backends/bosminer.py
+++ b/pyasic/miners/_backends/bosminer.py
@@ -15,7 +15,7 @@
import ipaddress
import logging
import json
-from typing import Union
+from typing import Union, List
import toml
@@ -24,7 +24,7 @@ from pyasic.miners.base import BaseMiner
from pyasic.API.bosminer import BOSMinerAPI
from pyasic.errors import APIError
-from pyasic.data.error_codes import BraiinsOSError
+from pyasic.data.error_codes import BraiinsOSError, MinerErrorData
from pyasic.data import MinerData
from pyasic.config import MinerConfig
@@ -103,6 +103,20 @@ class BOSMiner(BaseMiner):
return True
return False
+ async def stop_mining(self) -> bool:
+ data = await self.api.pause()
+ if data.get("PAUSE"):
+ if data["PAUSE"][0]:
+ return True
+ return False
+
+ async def resume_mining(self) -> bool:
+ data = await self.api.resume()
+ if data.get("RESUME"):
+ if data["RESUME"][0]:
+ return True
+ return False
+
async def reboot(self) -> bool:
"""Reboots power to the physical miner."""
logging.debug(f"{self}: Sending reboot command.")
@@ -242,7 +256,7 @@ class BOSMiner(BaseMiner):
self.light = True
return self.light
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
tunerstatus = None
errors = []
diff --git a/pyasic/miners/_backends/bosminer_old.py b/pyasic/miners/_backends/bosminer_old.py
index 9768c1c9..eef574a6 100644
--- a/pyasic/miners/_backends/bosminer_old.py
+++ b/pyasic/miners/_backends/bosminer_old.py
@@ -15,12 +15,13 @@
import logging
import ipaddress
-from typing import Union
+from typing import Union, List
from pyasic.API.bosminer import BOSMinerAPI
from pyasic.miners.base import BaseMiner
from pyasic.config import MinerConfig
from pyasic.data import MinerData
+from pyasic.data.error_codes import MinerErrorData
class BOSMinerOld(BaseMiner):
@@ -77,7 +78,7 @@ class BOSMinerOld(BaseMiner):
async def get_config(self) -> None:
return None
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
return []
async def get_hostname(self) -> str:
@@ -95,6 +96,12 @@ class BOSMinerOld(BaseMiner):
async def restart_backend(self) -> bool:
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
return None
diff --git a/pyasic/miners/_backends/btminer.py b/pyasic/miners/_backends/btminer.py
index 4df0c608..ba945026 100644
--- a/pyasic/miners/_backends/btminer.py
+++ b/pyasic/miners/_backends/btminer.py
@@ -14,7 +14,7 @@
import ipaddress
import logging
-from typing import Union
+from typing import Union, List
from pyasic.API.btminer import BTMinerAPI
@@ -22,7 +22,7 @@ from pyasic.miners.base import BaseMiner
from pyasic.errors import APIError
from pyasic.data import MinerData
-from pyasic.data.error_codes import WhatsminerError
+from pyasic.data.error_codes import WhatsminerError, MinerErrorData
from pyasic.config import MinerConfig
from pyasic.settings import PyasicSettings
@@ -156,13 +156,44 @@ class BTMiner(BaseMiner):
return True
return False
- async def get_errors(self) -> list:
- return []
+ async def get_errors(self) -> List[MinerErrorData]:
+ data = []
+
+ summary_data = await self.api.summary()
+ if summary_data[0].get("Error Code Count"):
+ for i in range(summary_data[0]["Error Code Count"]):
+ if summary_data[0].get(f"Error Code {i}"):
+ data.append(
+ WhatsminerError(error_code=summary_data[0][f"Error Code {i}"])
+ )
+ return data
async def reboot(self) -> bool:
+ data = await self.api.reboot()
+ if data.get("Msg"):
+ if data["Msg"] == "API command OK":
+ return True
return False
async def restart_backend(self) -> bool:
+ data = await self.api.restart()
+ if data.get("Msg"):
+ if data["Msg"] == "API command OK":
+ return True
+ return False
+
+ async def stop_mining(self) -> bool:
+ data = await self.api.power_off(respbefore=True)
+ if data.get("Msg"):
+ if data["Msg"] == "API command OK":
+ return True
+ return False
+
+ async def resume_mining(self) -> bool:
+ data = await self.api.power_on()
+ if data.get("Msg"):
+ if data["Msg"] == "API command OK":
+ return True
return False
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
diff --git a/pyasic/miners/_backends/cgminer.py b/pyasic/miners/_backends/cgminer.py
index 89426b05..99c05e9c 100644
--- a/pyasic/miners/_backends/cgminer.py
+++ b/pyasic/miners/_backends/cgminer.py
@@ -14,7 +14,7 @@
import ipaddress
import logging
-from typing import Union
+from typing import Union, List
from pyasic.API.cgminer import CGMinerAPI
@@ -23,6 +23,7 @@ from pyasic.errors import APIError
from pyasic.config import MinerConfig
from pyasic.data import MinerData
+from pyasic.data.error_codes import MinerErrorData
from pyasic.settings import PyasicSettings
@@ -118,8 +119,7 @@ class CGMiner(BaseMiner):
return True
return False
- async def start_cgminer(self) -> None:
- """Start cgminer hashing process."""
+ async def resume_mining(self) -> bool:
commands = [
"mkdir -p /etc/tmp/",
'echo "*/3 * * * * /usr/bin/cgminer-monitor" > /etc/tmp/root',
@@ -128,9 +128,9 @@ class CGMiner(BaseMiner):
]
commands = ";".join(commands)
await self.send_ssh_command(commands)
+ return True
- async def stop_cgminer(self) -> None:
- """Restart cgminer hashing process."""
+ async def stop_mining(self) -> bool:
commands = [
"mkdir -p /etc/tmp/",
'echo "" > /etc/tmp/root',
@@ -139,6 +139,7 @@ class CGMiner(BaseMiner):
]
commands = ";".join(commands)
await self.send_ssh_command(commands)
+ return True
async def get_config(self) -> str:
"""Gets the config for the miner and sets it as `self.config`.
@@ -163,7 +164,7 @@ class CGMiner(BaseMiner):
async def fault_light_on(self) -> bool:
return False
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
return []
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
diff --git a/pyasic/miners/antminer/bmminer/X19/X19.py b/pyasic/miners/antminer/bmminer/X19/X19.py
index 9e3ea878..c31a0ff0 100644
--- a/pyasic/miners/antminer/bmminer/X19/X19.py
+++ b/pyasic/miners/antminer/bmminer/X19/X19.py
@@ -15,7 +15,7 @@
from pyasic.miners._backends import BMMiner # noqa - Ignore access to _module
from pyasic.config import MinerConfig
-from pyasic.data.error_codes import X19Error
+from pyasic.data.error_codes import X19Error, MinerErrorData
from pyasic.settings import PyasicSettings
import httpx
@@ -132,7 +132,7 @@ class BMMinerX19(BMMiner):
return True
return False
- async def get_errors(self) -> List[X19Error]:
+ async def get_errors(self) -> List[MinerErrorData]:
errors = []
url = f"http://{self.ip}/cgi-bin/summary.cgi"
auth = httpx.DigestAuth(self.uname, self.pwd)
@@ -147,12 +147,14 @@ class BMMinerX19(BMMiner):
errors.append(X19Error(item["msg"]))
return errors
- async def stop_mining(self) -> None:
+ async def stop_mining(self) -> bool:
cfg = await self.get_config()
cfg.autotuning_wattage = 0
await self.send_config(cfg)
+ return True
- async def resume_mining(self):
+ async def resume_mining(self) -> bool:
cfg = await self.get_config()
cfg.autotuning_wattage = 1
await self.send_config(cfg)
+ return True
diff --git a/pyasic/miners/avalonminer/cgminer/A10X/A10X.py b/pyasic/miners/avalonminer/cgminer/A10X/A10X.py
index 9fca43b4..d4073da1 100644
--- a/pyasic/miners/avalonminer/cgminer/A10X/A10X.py
+++ b/pyasic/miners/avalonminer/cgminer/A10X/A10X.py
@@ -51,6 +51,12 @@ class CGMinerA10X(CGMiner):
return True
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
"""Configures miner with yaml config."""
raise NotImplementedError
diff --git a/pyasic/miners/avalonminer/cgminer/A7X/A7X.py b/pyasic/miners/avalonminer/cgminer/A7X/A7X.py
index 3ca3c394..459b4af7 100644
--- a/pyasic/miners/avalonminer/cgminer/A7X/A7X.py
+++ b/pyasic/miners/avalonminer/cgminer/A7X/A7X.py
@@ -51,6 +51,12 @@ class CGMinerA7X(CGMiner):
return True
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
"""Configures miner with yaml config."""
raise NotImplementedError
diff --git a/pyasic/miners/avalonminer/cgminer/A8X/A8X.py b/pyasic/miners/avalonminer/cgminer/A8X/A8X.py
index 76a3470a..1f47cb42 100644
--- a/pyasic/miners/avalonminer/cgminer/A8X/A8X.py
+++ b/pyasic/miners/avalonminer/cgminer/A8X/A8X.py
@@ -51,6 +51,12 @@ class CGMinerA8X(CGMiner):
return True
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
"""Configures miner with yaml config."""
raise NotImplementedError
diff --git a/pyasic/miners/avalonminer/cgminer/A9X/A921.py b/pyasic/miners/avalonminer/cgminer/A9X/A921.py
index 8beba58f..959bc3f7 100644
--- a/pyasic/miners/avalonminer/cgminer/A9X/A921.py
+++ b/pyasic/miners/avalonminer/cgminer/A9X/A921.py
@@ -52,6 +52,12 @@ class CGMinerAvalon921(CGMiner, Avalon921):
return True
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
"""Configures miner with yaml config."""
raise NotImplementedError
diff --git a/pyasic/miners/base.py b/pyasic/miners/base.py
index 01de23fb..fcdbe964 100644
--- a/pyasic/miners/base.py
+++ b/pyasic/miners/base.py
@@ -25,6 +25,7 @@ from pyasic.data.error_codes import (
BraiinsOSError,
InnosiliconError,
X19Error,
+ MinerErrorData,
)
@@ -181,9 +182,7 @@ class BaseMiner(ABC):
pass
@abstractmethod
- async def get_errors(
- self,
- ) -> List[Union[WhatsminerError, BraiinsOSError, InnosiliconError, X19Error]]:
+ async def get_errors(self) -> List[MinerErrorData]:
"""Get a list of the errors the miner is experiencing.
Returns:
@@ -200,5 +199,23 @@ class BaseMiner(ABC):
"""
return MinerData(ip=str(self.ip))
+ @abstractmethod
+ async def stop_mining(self) -> bool:
+ """Stop the mining process of the miner.
+
+ Returns:
+ A boolean value of the success of stopping the mining process.
+ """
+ pass
+
+ @abstractmethod
+ async def resume_mining(self) -> bool:
+ """Stop the mining process of the miner.
+
+ Returns:
+ A boolean value of the success of resuming the mining process.
+ """
+ pass
+
AnyMiner = TypeVar("AnyMiner", bound=BaseMiner)
diff --git a/pyasic/miners/innosilicon/cgminer/T3X/T3H_Plus.py b/pyasic/miners/innosilicon/cgminer/T3X/T3H_Plus.py
index 49e8365c..39331c89 100644
--- a/pyasic/miners/innosilicon/cgminer/T3X/T3H_Plus.py
+++ b/pyasic/miners/innosilicon/cgminer/T3X/T3H_Plus.py
@@ -15,14 +15,14 @@
from pyasic.miners._backends import CGMiner # noqa - Ignore access to _module
from pyasic.miners._types import InnosiliconT3HPlus # noqa - Ignore access to _module
from pyasic.data import MinerData
-from pyasic.data.error_codes import InnosiliconError
+from pyasic.data.error_codes import InnosiliconError, MinerErrorData
from pyasic.settings import PyasicSettings
from pyasic.config import MinerConfig
from pyasic.errors import APIError
import httpx
import warnings
-from typing import Union
+from typing import Union, List
import logging
@@ -142,7 +142,7 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
"updatePools", data=config.as_inno(user_suffix=user_suffix)
)
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
errors = []
try:
data = await self.send_web_command("getErrorDetail")
diff --git a/pyasic/miners/unknown.py b/pyasic/miners/unknown.py
index 555110d5..4d8e1feb 100644
--- a/pyasic/miners/unknown.py
+++ b/pyasic/miners/unknown.py
@@ -12,10 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import List
+
from pyasic.API.unknown import UnknownAPI
from pyasic.miners.base import BaseMiner
from pyasic.config import MinerConfig
from pyasic.data import MinerData
+from pyasic.data.error_codes import MinerErrorData
class UnknownMiner(BaseMiner):
@@ -48,7 +51,7 @@ class UnknownMiner(BaseMiner):
async def get_config(self) -> None:
return None
- async def get_errors(self) -> list:
+ async def get_errors(self) -> List[MinerErrorData]:
return []
async def get_mac(self) -> str:
@@ -60,6 +63,12 @@ class UnknownMiner(BaseMiner):
async def restart_backend(self) -> bool:
return False
+ async def stop_mining(self) -> bool:
+ return False
+
+ async def resume_mining(self) -> bool:
+ return False
+
async def send_config(self, config: MinerConfig, user_suffix: str = None) -> None:
return None