feature: add more hiveon functionality

This commit is contained in:
Upstream Data
2024-12-10 09:21:11 -07:00
parent 055d633c91
commit 97d2c4ac34
7 changed files with 224 additions and 27 deletions

View File

@@ -299,3 +299,7 @@ class MinerConfig(BaseModel):
@classmethod
def from_hammer(cls, *args, **kwargs) -> "MinerConfig":
return cls.from_am_modern(*args, **kwargs)
@classmethod
def from_hiveon_modern(cls, web_conf: dict) -> "MinerConfig":
return cls.from_am_modern(web_conf)

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import Hiveon
from pyasic.miners.backends import HiveonModern
from pyasic.miners.device.models import (
S19,
S19L,
@@ -35,65 +35,65 @@ from pyasic.miners.device.models import (
)
class HiveonS19(Hiveon, S19):
class HiveonS19(HiveonModern, S19):
pass
class HiveonS19Plus(Hiveon, S19Plus):
class HiveonS19Plus(HiveonModern, S19Plus):
pass
class HiveonS19i(Hiveon, S19i):
class HiveonS19i(HiveonModern, S19i):
pass
class HiveonS19Pro(Hiveon, S19Pro):
class HiveonS19Pro(HiveonModern, S19Pro):
pass
class HiveonS19ProPlus(Hiveon, S19ProPlus):
class HiveonS19ProPlus(HiveonModern, S19ProPlus):
pass
class HiveonS19XP(Hiveon, S19XP):
class HiveonS19XP(HiveonModern, S19XP):
pass
class HiveonS19a(Hiveon, S19a):
class HiveonS19a(HiveonModern, S19a):
pass
class HiveonS19aPro(Hiveon, S19aPro):
class HiveonS19aPro(HiveonModern, S19aPro):
pass
class HiveonS19j(Hiveon, S19j):
class HiveonS19j(HiveonModern, S19j):
pass
class HiveonS19jNoPIC(Hiveon, S19jNoPIC):
class HiveonS19jNoPIC(HiveonModern, S19jNoPIC):
pass
class HiveonS19jPro(Hiveon, S19jPro):
class HiveonS19jPro(HiveonModern, S19jPro):
pass
class HiveonS19L(Hiveon, S19L):
class HiveonS19L(HiveonModern, S19L):
pass
class HiveonS19ProHydro(Hiveon, S19ProHydro):
class HiveonS19ProHydro(HiveonModern, S19ProHydro):
pass
class HiveonS19Hydro(Hiveon, S19Hydro):
class HiveonS19Hydro(HiveonModern, S19Hydro):
pass
class HiveonS19ProPlusHydro(Hiveon, S19ProPlusHydro):
class HiveonS19ProPlusHydro(HiveonModern, S19ProPlusHydro):
pass
class HiveonS19KPro(Hiveon, S19KPro):
class HiveonS19KPro(HiveonModern, S19KPro):
pass

View File

@@ -14,9 +14,9 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import Hiveon
from pyasic.miners.backends import HiveonModern
from pyasic.miners.device.models import T19
class HiveonT19(Hiveon, T19):
class HiveonT19(HiveonModern, T19):
pass

View File

@@ -21,7 +21,7 @@ import asyncssh
from pyasic.data import HashBoard
from pyasic.device.algorithm import AlgoHashRate, HashUnit
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.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
##################################################

View File

@@ -25,7 +25,7 @@ from .cgminer import CGMiner
from .epic import ePIC
from .goldshell import GoldshellMiner
from .hammer import BlackMiner
from .hiveon import Hiveon
from .hiveon import HiveonModern, HiveonOld
from .iceriver import IceRiver
from .innosilicon import Innosilicon
from .luxminer import LUXMiner

View File

@@ -16,13 +16,28 @@
from typing import Optional
from pyasic import APIError
from pyasic.config import MinerConfig, MiningModeConfig
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.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(
"_get_api_ver",
[RPCAPICommand("rpc_version", "version")],
@@ -59,16 +74,194 @@ HIVEON_DATA_LOC = DataLocations(
"_get_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):
data_locations = HIVEON_DATA_LOC
class HiveonModern(HiveonFirmware, BMMiner):
data_locations = HIVEON_MODERN_DATA_LOC
web: 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]:
if not rpc_stats:
try:

View File

@@ -424,7 +424,7 @@ MINER_CLASSES = {
"BLOCKMINER 720I": ePICBlockMiner720i,
},
MinerTypes.HIVEON: {
None: Hiveon,
None: HiveonModern,
"ANTMINER T9": HiveonT9,
"ANTMINER S19JPRO": HiveonS19jPro,
},