feature: add more hiveon functionality
This commit is contained in:
@@ -299,3 +299,7 @@ class MinerConfig(BaseModel):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_hammer(cls, *args, **kwargs) -> "MinerConfig":
|
def from_hammer(cls, *args, **kwargs) -> "MinerConfig":
|
||||||
return cls.from_am_modern(*args, **kwargs)
|
return cls.from_am_modern(*args, **kwargs)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_hiveon_modern(cls, web_conf: dict) -> "MinerConfig":
|
||||||
|
return cls.from_am_modern(web_conf)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import Hiveon
|
from pyasic.miners.backends import HiveonModern
|
||||||
from pyasic.miners.device.models import (
|
from pyasic.miners.device.models import (
|
||||||
S19,
|
S19,
|
||||||
S19L,
|
S19L,
|
||||||
@@ -35,65 +35,65 @@ from pyasic.miners.device.models import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19(Hiveon, S19):
|
class HiveonS19(HiveonModern, S19):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19Plus(Hiveon, S19Plus):
|
class HiveonS19Plus(HiveonModern, S19Plus):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19i(Hiveon, S19i):
|
class HiveonS19i(HiveonModern, S19i):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19Pro(Hiveon, S19Pro):
|
class HiveonS19Pro(HiveonModern, S19Pro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19ProPlus(Hiveon, S19ProPlus):
|
class HiveonS19ProPlus(HiveonModern, S19ProPlus):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19XP(Hiveon, S19XP):
|
class HiveonS19XP(HiveonModern, S19XP):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19a(Hiveon, S19a):
|
class HiveonS19a(HiveonModern, S19a):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19aPro(Hiveon, S19aPro):
|
class HiveonS19aPro(HiveonModern, S19aPro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19j(Hiveon, S19j):
|
class HiveonS19j(HiveonModern, S19j):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19jNoPIC(Hiveon, S19jNoPIC):
|
class HiveonS19jNoPIC(HiveonModern, S19jNoPIC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19jPro(Hiveon, S19jPro):
|
class HiveonS19jPro(HiveonModern, S19jPro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19L(Hiveon, S19L):
|
class HiveonS19L(HiveonModern, S19L):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19ProHydro(Hiveon, S19ProHydro):
|
class HiveonS19ProHydro(HiveonModern, S19ProHydro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19Hydro(Hiveon, S19Hydro):
|
class HiveonS19Hydro(HiveonModern, S19Hydro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19ProPlusHydro(Hiveon, S19ProPlusHydro):
|
class HiveonS19ProPlusHydro(HiveonModern, S19ProPlusHydro):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class HiveonS19KPro(Hiveon, S19KPro):
|
class HiveonS19KPro(HiveonModern, S19KPro):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
from pyasic.miners.backends import Hiveon
|
from pyasic.miners.backends import HiveonModern
|
||||||
from pyasic.miners.device.models import T19
|
from pyasic.miners.device.models import T19
|
||||||
|
|
||||||
|
|
||||||
class HiveonT19(Hiveon, T19):
|
class HiveonT19(HiveonModern, T19):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import asyncssh
|
|||||||
from pyasic.data import HashBoard
|
from pyasic.data import HashBoard
|
||||||
from pyasic.device.algorithm import AlgoHashRate, HashUnit
|
from pyasic.device.algorithm import AlgoHashRate, HashUnit
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
from pyasic.miners.backends import Hiveon
|
from pyasic.miners.backends import HiveonOld
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||||
from pyasic.miners.device.models import T9
|
from pyasic.miners.device.models import T9
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ HIVEON_T9_DATA_LOC = DataLocations(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HiveonT9(Hiveon, T9):
|
class HiveonT9(HiveonOld, T9):
|
||||||
data_locations = HIVEON_T9_DATA_LOC
|
data_locations = HIVEON_T9_DATA_LOC
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from .cgminer import CGMiner
|
|||||||
from .epic import ePIC
|
from .epic import ePIC
|
||||||
from .goldshell import GoldshellMiner
|
from .goldshell import GoldshellMiner
|
||||||
from .hammer import BlackMiner
|
from .hammer import BlackMiner
|
||||||
from .hiveon import Hiveon
|
from .hiveon import HiveonModern, HiveonOld
|
||||||
from .iceriver import IceRiver
|
from .iceriver import IceRiver
|
||||||
from .innosilicon import Innosilicon
|
from .innosilicon import Innosilicon
|
||||||
from .luxminer import LUXMiner
|
from .luxminer import LUXMiner
|
||||||
|
|||||||
@@ -16,13 +16,28 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pyasic import APIError
|
from pyasic import APIError
|
||||||
|
from pyasic.config import MinerConfig, MiningModeConfig
|
||||||
from pyasic.miners.backends import BMMiner
|
from pyasic.miners.backends import BMMiner
|
||||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
from pyasic.miners.data import (
|
||||||
|
DataFunction,
|
||||||
|
DataLocations,
|
||||||
|
DataOptions,
|
||||||
|
RPCAPICommand,
|
||||||
|
WebAPICommand,
|
||||||
|
)
|
||||||
from pyasic.miners.device.firmware import HiveonFirmware
|
from pyasic.miners.device.firmware import HiveonFirmware
|
||||||
from pyasic.web.hiveon import HiveonWebAPI
|
from pyasic.web.hiveon import HiveonWebAPI
|
||||||
|
|
||||||
HIVEON_DATA_LOC = DataLocations(
|
HIVEON_MODERN_DATA_LOC = DataLocations(
|
||||||
**{
|
**{
|
||||||
|
str(DataOptions.MAC): DataFunction(
|
||||||
|
"_get_mac",
|
||||||
|
[WebAPICommand("web_get_system_info", "get_system_info")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HOSTNAME): DataFunction(
|
||||||
|
"_get_hostname",
|
||||||
|
[WebAPICommand("web_get_system_info", "get_system_info")],
|
||||||
|
),
|
||||||
str(DataOptions.API_VERSION): DataFunction(
|
str(DataOptions.API_VERSION): DataFunction(
|
||||||
"_get_api_ver",
|
"_get_api_ver",
|
||||||
[RPCAPICommand("rpc_version", "version")],
|
[RPCAPICommand("rpc_version", "version")],
|
||||||
@@ -59,16 +74,194 @@ HIVEON_DATA_LOC = DataLocations(
|
|||||||
"_get_pools",
|
"_get_pools",
|
||||||
[RPCAPICommand("rpc_pools", "pools")],
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
),
|
),
|
||||||
|
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||||
|
"_get_fault_light",
|
||||||
|
[WebAPICommand("web_get_blink_status", "get_blink_status")],
|
||||||
|
),
|
||||||
|
str(DataOptions.IS_MINING): DataFunction(
|
||||||
|
"_is_mining",
|
||||||
|
[WebAPICommand("web_get_conf", "get_miner_conf")],
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Hiveon(HiveonFirmware, BMMiner):
|
class HiveonModern(HiveonFirmware, BMMiner):
|
||||||
data_locations = HIVEON_DATA_LOC
|
data_locations = HIVEON_MODERN_DATA_LOC
|
||||||
|
|
||||||
web: HiveonWebAPI
|
web: HiveonWebAPI
|
||||||
_web_cls = HiveonWebAPI
|
_web_cls = HiveonWebAPI
|
||||||
|
|
||||||
|
async def get_config(self) -> MinerConfig:
|
||||||
|
data = await self.web.get_miner_conf()
|
||||||
|
if data:
|
||||||
|
self.config = MinerConfig.from_hiveon_modern(data)
|
||||||
|
return self.config
|
||||||
|
|
||||||
|
async def fault_light_on(self) -> bool:
|
||||||
|
data = await self.web.blink(blink=True)
|
||||||
|
if data:
|
||||||
|
if data.get("code") == "B000":
|
||||||
|
self.light = True
|
||||||
|
return self.light
|
||||||
|
|
||||||
|
async def fault_light_off(self) -> bool:
|
||||||
|
data = await self.web.blink(blink=False)
|
||||||
|
if data:
|
||||||
|
if data.get("code") == "B100":
|
||||||
|
self.light = False
|
||||||
|
return self.light
|
||||||
|
|
||||||
|
async def reboot(self) -> bool:
|
||||||
|
data = await self.web.reboot()
|
||||||
|
if data:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def stop_mining(self) -> bool:
|
||||||
|
cfg = await self.get_config()
|
||||||
|
cfg.miner_mode = MiningModeConfig.sleep()
|
||||||
|
await self.send_config(cfg)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def resume_mining(self) -> bool:
|
||||||
|
cfg = await self.get_config()
|
||||||
|
cfg.miner_mode = MiningModeConfig.normal()
|
||||||
|
await self.send_config(cfg)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def _get_wattage(self, rpc_stats: dict = None) -> Optional[int]:
|
||||||
|
if not rpc_stats:
|
||||||
|
try:
|
||||||
|
rpc_stats = await self.rpc.stats()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if rpc_stats:
|
||||||
|
boards = rpc_stats.get("STATS")
|
||||||
|
try:
|
||||||
|
wattage_raw = boards[1]["chain_power"]
|
||||||
|
except (KeyError, IndexError):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# parse wattage position out of raw data
|
||||||
|
return round(float(wattage_raw.split(" ")[0]))
|
||||||
|
|
||||||
|
async def _get_hostname(self, web_get_system_info: dict = None) -> Optional[str]:
|
||||||
|
if web_get_system_info is None:
|
||||||
|
try:
|
||||||
|
web_get_system_info = await self.web.get_system_info()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_get_system_info is not None:
|
||||||
|
try:
|
||||||
|
return web_get_system_info["hostname"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_mac(self, web_get_system_info: dict = None) -> Optional[str]:
|
||||||
|
if web_get_system_info is None:
|
||||||
|
try:
|
||||||
|
web_get_system_info = await self.web.get_system_info()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_get_system_info is not None:
|
||||||
|
try:
|
||||||
|
return web_get_system_info["macaddr"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = await self.web.get_network_info()
|
||||||
|
if data:
|
||||||
|
return data["macaddr"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def _get_fault_light(
|
||||||
|
self, web_get_blink_status: dict = None
|
||||||
|
) -> Optional[bool]:
|
||||||
|
if self.light:
|
||||||
|
return self.light
|
||||||
|
|
||||||
|
if web_get_blink_status is None:
|
||||||
|
try:
|
||||||
|
web_get_blink_status = await self.web.get_blink_status()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_get_blink_status is not None:
|
||||||
|
try:
|
||||||
|
self.light = web_get_blink_status["blink"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
return self.light
|
||||||
|
|
||||||
|
async def _is_mining(self, web_get_conf: dict = None) -> Optional[bool]:
|
||||||
|
if web_get_conf is None:
|
||||||
|
try:
|
||||||
|
web_get_conf = await self.web.get_miner_conf()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if web_get_conf is not None:
|
||||||
|
try:
|
||||||
|
if str(web_get_conf["bitmain-work-mode"]).isdigit():
|
||||||
|
return (
|
||||||
|
False if int(web_get_conf["bitmain-work-mode"]) == 1 else True
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
except LookupError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
HIVEON_OLD_DATA_LOC = DataLocations(
|
||||||
|
**{
|
||||||
|
str(DataOptions.API_VERSION): DataFunction(
|
||||||
|
"_get_api_ver",
|
||||||
|
[RPCAPICommand("rpc_version", "version")],
|
||||||
|
),
|
||||||
|
str(DataOptions.FW_VERSION): DataFunction(
|
||||||
|
"_get_fw_ver",
|
||||||
|
[RPCAPICommand("rpc_version", "version")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HASHRATE): DataFunction(
|
||||||
|
"_get_hashrate",
|
||||||
|
[RPCAPICommand("rpc_summary", "summary")],
|
||||||
|
),
|
||||||
|
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
|
||||||
|
"_get_expected_hashrate",
|
||||||
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
|
),
|
||||||
|
str(DataOptions.HASHBOARDS): DataFunction(
|
||||||
|
"_get_hashboards",
|
||||||
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
|
),
|
||||||
|
str(DataOptions.FANS): DataFunction(
|
||||||
|
"_get_fans",
|
||||||
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
|
),
|
||||||
|
str(DataOptions.UPTIME): DataFunction(
|
||||||
|
"_get_uptime",
|
||||||
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
|
),
|
||||||
|
str(DataOptions.POOLS): DataFunction(
|
||||||
|
"_get_pools",
|
||||||
|
[RPCAPICommand("rpc_pools", "pools")],
|
||||||
|
),
|
||||||
|
str(DataOptions.WATTAGE): DataFunction(
|
||||||
|
"_get_wattage",
|
||||||
|
[RPCAPICommand("rpc_stats", "stats")],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HiveonOld(HiveonFirmware, BMMiner):
|
||||||
|
data_locations = HIVEON_OLD_DATA_LOC
|
||||||
|
|
||||||
async def _get_wattage(self, rpc_stats: dict = None) -> Optional[int]:
|
async def _get_wattage(self, rpc_stats: dict = None) -> Optional[int]:
|
||||||
if not rpc_stats:
|
if not rpc_stats:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ MINER_CLASSES = {
|
|||||||
"BLOCKMINER 720I": ePICBlockMiner720i,
|
"BLOCKMINER 720I": ePICBlockMiner720i,
|
||||||
},
|
},
|
||||||
MinerTypes.HIVEON: {
|
MinerTypes.HIVEON: {
|
||||||
None: Hiveon,
|
None: HiveonModern,
|
||||||
"ANTMINER T9": HiveonT9,
|
"ANTMINER T9": HiveonT9,
|
||||||
"ANTMINER S19JPRO": HiveonS19jPro,
|
"ANTMINER S19JPRO": HiveonS19jPro,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user