Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea55fed8d1 | ||
|
|
f5fd539eba | ||
|
|
51a56f441c | ||
|
|
54310b1d79 | ||
|
|
cb30b761dc | ||
|
|
cb50a7cac8 | ||
|
|
738af245cb | ||
|
|
71e9af1b91 | ||
|
|
1cd2566d0a | ||
|
|
1f1e5f23a2 | ||
|
|
3394234e4f | ||
|
|
e9882124ff | ||
|
|
1e5b19c149 | ||
|
|
c9339fec2f |
@@ -245,7 +245,9 @@ class MinerConfig:
|
|||||||
fan_speed: Manual fan speed to run the fan at (only if temp_mode == "manual").
|
fan_speed: Manual fan speed to run the fan at (only if temp_mode == "manual").
|
||||||
asicboost: Whether or not to enable asicboost.
|
asicboost: Whether or not to enable asicboost.
|
||||||
autotuning_enabled: Whether or not to enable autotuning.
|
autotuning_enabled: Whether or not to enable autotuning.
|
||||||
|
autotuning_mode: Autotuning mode, either "wattage" or "hashrate".
|
||||||
autotuning_wattage: The wattage to use when autotuning.
|
autotuning_wattage: The wattage to use when autotuning.
|
||||||
|
autotuning_hashrate: The hashrate to use when autotuning.
|
||||||
dps_enabled: Whether or not to enable dynamic power scaling.
|
dps_enabled: Whether or not to enable dynamic power scaling.
|
||||||
dps_power_step: The amount of power to reduce autotuning by when the miner reaches dangerous temp.
|
dps_power_step: The amount of power to reduce autotuning by when the miner reaches dangerous temp.
|
||||||
dps_min_power: The minimum power to reduce autotuning to.
|
dps_min_power: The minimum power to reduce autotuning to.
|
||||||
@@ -266,7 +268,9 @@ class MinerConfig:
|
|||||||
asicboost: bool = None
|
asicboost: bool = None
|
||||||
|
|
||||||
autotuning_enabled: bool = True
|
autotuning_enabled: bool = True
|
||||||
autotuning_wattage: int = 900
|
autotuning_mode: Literal["power", "hashrate"] = None
|
||||||
|
autotuning_wattage: int = None
|
||||||
|
autotuning_hashrate: int = None
|
||||||
|
|
||||||
dps_enabled: bool = None
|
dps_enabled: bool = None
|
||||||
dps_power_step: int = None
|
dps_power_step: int = None
|
||||||
@@ -349,14 +353,20 @@ class MinerConfig:
|
|||||||
self.autotuning_enabled = data[key][_key]
|
self.autotuning_enabled = data[key][_key]
|
||||||
elif _key == "psu_power_limit":
|
elif _key == "psu_power_limit":
|
||||||
self.autotuning_wattage = data[key][_key]
|
self.autotuning_wattage = data[key][_key]
|
||||||
|
elif _key == "power_target":
|
||||||
|
self.autotuning_wattage = data[key][_key]
|
||||||
|
elif _key == "hashrate_target":
|
||||||
|
self.autotuning_hashrate = data[key][_key]
|
||||||
|
elif _key == "mode":
|
||||||
|
self.autotuning_mode = data[key][_key].replace("_target", "")
|
||||||
|
|
||||||
if key == "power_scaling":
|
if key in ["power_scaling", "performance_scaling"]:
|
||||||
for _key in data[key].keys():
|
for _key in data[key].keys():
|
||||||
if _key == "enabled":
|
if _key == "enabled":
|
||||||
self.dps_enabled = data[key][_key]
|
self.dps_enabled = data[key][_key]
|
||||||
elif _key == "power_step":
|
elif _key == "power_step":
|
||||||
self.dps_power_step = data[key][_key]
|
self.dps_power_step = data[key][_key]
|
||||||
elif _key == "min_psu_power_limit":
|
elif _key in ["min_psu_power_limit", "min_power_target"]:
|
||||||
self.dps_min_power = data[key][_key]
|
self.dps_min_power = data[key][_key]
|
||||||
elif _key == "shutdown_enabled":
|
elif _key == "shutdown_enabled":
|
||||||
self.dps_shutdown_enabled = data[key][_key]
|
self.dps_shutdown_enabled = data[key][_key]
|
||||||
@@ -481,8 +491,8 @@ class MinerConfig:
|
|||||||
cfg = {
|
cfg = {
|
||||||
"format": {
|
"format": {
|
||||||
"version": "1.2+",
|
"version": "1.2+",
|
||||||
"model": f"Antminer {model}",
|
"model": f"Antminer {model.replace('j', 'J')}",
|
||||||
"generator": "Upstream Config Utility",
|
"generator": "pyasic",
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
},
|
},
|
||||||
"group": [
|
"group": [
|
||||||
@@ -499,7 +509,17 @@ class MinerConfig:
|
|||||||
if self.autotuning_enabled or self.autotuning_wattage:
|
if self.autotuning_enabled or self.autotuning_wattage:
|
||||||
cfg["autotuning"] = {}
|
cfg["autotuning"] = {}
|
||||||
if self.autotuning_enabled:
|
if self.autotuning_enabled:
|
||||||
cfg["autotuning"]["enabled"] = self.autotuning_enabled
|
cfg["autotuning"]["enabled"] = True
|
||||||
|
else:
|
||||||
|
cfg["autotuning"]["enabled"] = False
|
||||||
|
if self.autotuning_mode:
|
||||||
|
cfg["format"]["version"] = "2.0"
|
||||||
|
cfg["autotuning"]["mode"] = self.autotuning_mode + "_target"
|
||||||
|
if self.autotuning_wattage:
|
||||||
|
cfg["autotuning"]["power_target"] = self.autotuning_wattage
|
||||||
|
elif self.autotuning_hashrate:
|
||||||
|
cfg["autotuning"]["hashrate_target"] = self.autotuning_hashrate
|
||||||
|
else:
|
||||||
if self.autotuning_wattage:
|
if self.autotuning_wattage:
|
||||||
cfg["autotuning"]["psu_power_limit"] = self.autotuning_wattage
|
cfg["autotuning"]["psu_power_limit"] = self.autotuning_wattage
|
||||||
|
|
||||||
@@ -525,6 +545,9 @@ class MinerConfig:
|
|||||||
if self.dps_power_step:
|
if self.dps_power_step:
|
||||||
cfg["power_scaling"]["power_step"] = self.dps_power_step
|
cfg["power_scaling"]["power_step"] = self.dps_power_step
|
||||||
if self.dps_min_power:
|
if self.dps_min_power:
|
||||||
|
if cfg["format"]["version"] == "2.0":
|
||||||
|
cfg["power_scaling"]["min_power_target"] = self.dps_min_power
|
||||||
|
else:
|
||||||
cfg["power_scaling"]["min_psu_power_limit"] = self.dps_min_power
|
cfg["power_scaling"]["min_psu_power_limit"] = self.dps_min_power
|
||||||
if self.dps_shutdown_enabled:
|
if self.dps_shutdown_enabled:
|
||||||
cfg["power_scaling"]["shutdown_enabled"] = self.dps_shutdown_enabled
|
cfg["power_scaling"]["shutdown_enabled"] = self.dps_shutdown_enabled
|
||||||
|
|||||||
@@ -198,11 +198,8 @@ class BOSMiner(BaseMiner):
|
|||||||
return self.config
|
return self.config
|
||||||
if conn:
|
if conn:
|
||||||
async with conn:
|
async with conn:
|
||||||
logging.debug(f"{self}: Opening SFTP connection.")
|
# good ol' BBB compatibility :/
|
||||||
async with conn.start_sftp_client() as sftp:
|
toml_data = toml.loads((await conn.run("cat /etc/bosminer.toml")).stdout)
|
||||||
logging.debug(f"{self}: Reading config file.")
|
|
||||||
async with sftp.open("/etc/bosminer.toml") as file:
|
|
||||||
toml_data = toml.loads(await file.read())
|
|
||||||
logging.debug(f"{self}: Converting config file.")
|
logging.debug(f"{self}: Converting config file.")
|
||||||
cfg = MinerConfig().from_raw(toml_data)
|
cfg = MinerConfig().from_raw(toml_data)
|
||||||
self.config = cfg
|
self.config = cfg
|
||||||
@@ -219,6 +216,12 @@ class BOSMiner(BaseMiner):
|
|||||||
except (asyncssh.Error, OSError):
|
except (asyncssh.Error, OSError):
|
||||||
return None
|
return None
|
||||||
async with conn:
|
async with conn:
|
||||||
|
# BBB check because bitmain suxx
|
||||||
|
bbb_check = await conn.run("if [ ! -f /etc/init.d/bosminer ]; then echo '1'; else echo '0'; fi;")
|
||||||
|
|
||||||
|
bbb = bbb_check.stdout.strip() == "1"
|
||||||
|
|
||||||
|
if not bbb:
|
||||||
await conn.run("/etc/init.d/bosminer stop")
|
await conn.run("/etc/init.d/bosminer stop")
|
||||||
logging.debug(f"{self}: Opening SFTP connection.")
|
logging.debug(f"{self}: Opening SFTP connection.")
|
||||||
async with conn.start_sftp_client() as sftp:
|
async with conn.start_sftp_client() as sftp:
|
||||||
@@ -228,6 +231,14 @@ class BOSMiner(BaseMiner):
|
|||||||
logging.debug(f"{self}: Restarting BOSMiner")
|
logging.debug(f"{self}: Restarting BOSMiner")
|
||||||
await conn.run("/etc/init.d/bosminer start")
|
await conn.run("/etc/init.d/bosminer start")
|
||||||
|
|
||||||
|
# I really hate BBB, please get rid of it if you have it
|
||||||
|
else:
|
||||||
|
await conn.run("/etc/init.d/S99bosminer stop")
|
||||||
|
logging.debug(f"{self}: BBB sending config")
|
||||||
|
await conn.run("echo '" + toml_conf + "' > /etc/bosminer.toml")
|
||||||
|
logging.debug(f"{self}: BBB restarting bosminer.")
|
||||||
|
await conn.run("/etc/init.d/S99bosminer start")
|
||||||
|
|
||||||
async def set_power_limit(self, wattage: int) -> bool:
|
async def set_power_limit(self, wattage: int) -> bool:
|
||||||
try:
|
try:
|
||||||
cfg = await self.get_config()
|
cfg = await self.get_config()
|
||||||
@@ -483,10 +494,9 @@ class BOSMiner(BaseMiner):
|
|||||||
api_devs = d["devs"][0]
|
api_devs = d["devs"][0]
|
||||||
except (KeyError, IndexError):
|
except (KeyError, IndexError):
|
||||||
api_devs = None
|
api_devs = None
|
||||||
|
|
||||||
if api_temps:
|
if api_temps:
|
||||||
try:
|
try:
|
||||||
offset = 6 if api_temps["TEMPS"][0]["ID"] in [6, 7, 8] else 0
|
offset = 6 if api_temps["TEMPS"][0]["ID"] in [6, 7, 8] else 1
|
||||||
|
|
||||||
for board in api_temps["TEMPS"]:
|
for board in api_temps["TEMPS"]:
|
||||||
_id = board["ID"] - offset
|
_id = board["ID"] - offset
|
||||||
@@ -499,7 +509,7 @@ class BOSMiner(BaseMiner):
|
|||||||
|
|
||||||
if api_devdetails:
|
if api_devdetails:
|
||||||
try:
|
try:
|
||||||
offset = 6 if api_devdetails["DEVDETAILS"][0]["ID"] in [6, 7, 8] else 0
|
offset = 6 if api_devdetails["DEVDETAILS"][0]["ID"] in [6, 7, 8] else 1
|
||||||
|
|
||||||
for board in api_devdetails["DEVDETAILS"]:
|
for board in api_devdetails["DEVDETAILS"]:
|
||||||
_id = board["ID"] - offset
|
_id = board["ID"] - offset
|
||||||
@@ -511,7 +521,7 @@ class BOSMiner(BaseMiner):
|
|||||||
|
|
||||||
if api_devs:
|
if api_devs:
|
||||||
try:
|
try:
|
||||||
offset = 6 if api_devs["DEVS"][0]["ID"] in [6, 7, 8] else 0
|
offset = 6 if api_devs["DEVS"][0]["ID"] in [6, 7, 8] else 1
|
||||||
|
|
||||||
for board in api_devs["DEVS"]:
|
for board in api_devs["DEVS"]:
|
||||||
_id = board["ID"] - offset
|
_id = board["ID"] - offset
|
||||||
|
|||||||
@@ -136,10 +136,10 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
|
|
||||||
async def get_mac(
|
async def get_mac(
|
||||||
self,
|
self,
|
||||||
web_getAll: dict = None,
|
web_getAll: dict = None, # noqa
|
||||||
web_overview: dict = None, # noqa: named this way for automatic functionality
|
web_overview: dict = None, # noqa: named this way for automatic functionality
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
web_all_data = web_getAll
|
web_all_data = web_getAll.get("all")
|
||||||
if not web_all_data and not web_overview:
|
if not web_all_data and not web_overview:
|
||||||
try:
|
try:
|
||||||
web_overview = await self.send_web_command("overview")
|
web_overview = await self.send_web_command("overview")
|
||||||
@@ -183,7 +183,7 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
api_summary: dict = None,
|
api_summary: dict = None,
|
||||||
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
||||||
) -> Optional[float]:
|
) -> Optional[float]:
|
||||||
web_all_data = web_getAll
|
web_all_data = web_getAll.get("all")
|
||||||
if not api_summary and not web_all_data:
|
if not api_summary and not web_all_data:
|
||||||
try:
|
try:
|
||||||
api_summary = await self.api.summary()
|
api_summary = await self.api.summary()
|
||||||
@@ -209,7 +209,7 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
api_stats: dict = None,
|
api_stats: dict = None,
|
||||||
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
||||||
) -> List[HashBoard]:
|
) -> List[HashBoard]:
|
||||||
web_all_data = web_getAll
|
web_all_data = web_getAll.get("all")
|
||||||
hashboards = [
|
hashboards = [
|
||||||
HashBoard(slot=i, expected_chips=self.nominal_chips)
|
HashBoard(slot=i, expected_chips=self.nominal_chips)
|
||||||
for i in range(self.ideal_hashboards)
|
for i in range(self.ideal_hashboards)
|
||||||
@@ -231,8 +231,9 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
|
|
||||||
if api_stats:
|
if api_stats:
|
||||||
if api_stats.get("STATS"):
|
if api_stats.get("STATS"):
|
||||||
for idx, board in enumerate(api_stats["STATS"]):
|
for board in api_stats["STATS"]:
|
||||||
try:
|
try:
|
||||||
|
idx = board["Chain ID"]
|
||||||
chips = board["Num active chips"]
|
chips = board["Num active chips"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
@@ -242,14 +243,18 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
|
|
||||||
if web_all_data:
|
if web_all_data:
|
||||||
if web_all_data.get("chain"):
|
if web_all_data.get("chain"):
|
||||||
for idx, board in enumerate(web_all_data["chain"]):
|
for board in web_all_data["chain"]:
|
||||||
|
idx = board.get("ASC")
|
||||||
|
if idx is not None:
|
||||||
temp = board.get("Temp min")
|
temp = board.get("Temp min")
|
||||||
if temp:
|
if temp:
|
||||||
hashboards[idx].temp = round(temp)
|
hashboards[idx].temp = round(temp)
|
||||||
|
|
||||||
hashrate = board.get("Hash Rate H")
|
hashrate = board.get("Hash Rate H")
|
||||||
if hashrate:
|
if hashrate:
|
||||||
hashboards[idx].hashrate = round(hashrate / 1000000000000, 2)
|
hashboards[idx].hashrate = round(
|
||||||
|
hashrate / 1000000000000, 2
|
||||||
|
)
|
||||||
|
|
||||||
chip_temp = board.get("Temp max")
|
chip_temp = board.get("Temp max")
|
||||||
if chip_temp:
|
if chip_temp:
|
||||||
@@ -258,9 +263,11 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
return hashboards
|
return hashboards
|
||||||
|
|
||||||
async def get_wattage(
|
async def get_wattage(
|
||||||
self, web_getAll: dict = None
|
self,
|
||||||
) -> Optional[int]: # noqa: named this way for automatic functionality
|
web_getAll: dict = None,
|
||||||
web_all_data = web_getAll
|
api_stats: dict = None, # noqa: named this way for automatic functionality
|
||||||
|
) -> Optional[int]:
|
||||||
|
web_all_data = web_getAll.get("all")
|
||||||
if not web_all_data:
|
if not web_all_data:
|
||||||
try:
|
try:
|
||||||
web_all_data = await self.send_web_command("getAll")
|
web_all_data = await self.send_web_command("getAll")
|
||||||
@@ -275,11 +282,28 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if not api_stats:
|
||||||
|
try:
|
||||||
|
api_stats = await self.api.stats()
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if api_stats:
|
||||||
|
if api_stats.get("STATS"):
|
||||||
|
for board in api_stats["STATS"]:
|
||||||
|
try:
|
||||||
|
wattage = board["power"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
wattage = int(wattage)
|
||||||
|
return wattage
|
||||||
|
|
||||||
async def get_fans(
|
async def get_fans(
|
||||||
self,
|
self,
|
||||||
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
web_getAll: dict = None, # noqa: named this way for automatic functionality
|
||||||
) -> List[Fan]:
|
) -> List[Fan]:
|
||||||
web_all_data = web_getAll
|
web_all_data = web_getAll.get("all")
|
||||||
if not web_all_data:
|
if not web_all_data:
|
||||||
try:
|
try:
|
||||||
web_all_data = await self.send_web_command("getAll")
|
web_all_data = await self.send_web_command("getAll")
|
||||||
@@ -350,3 +374,24 @@ class CGMinerInnosiliconT3HPlus(CGMiner, InnosiliconT3HPlus):
|
|||||||
if not err == 0:
|
if not err == 0:
|
||||||
errors.append(InnosiliconError(error_code=err))
|
errors.append(InnosiliconError(error_code=err))
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
async def get_wattage_limit(self, web_getAll: dict = None) -> Optional[int]:
|
||||||
|
web_all_data = web_getAll.get("all")
|
||||||
|
if not web_all_data:
|
||||||
|
try:
|
||||||
|
web_all_data = await self.send_web_command("getAll")
|
||||||
|
except APIError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
web_all_data = web_all_data["all"]
|
||||||
|
|
||||||
|
if web_all_data:
|
||||||
|
try:
|
||||||
|
level = web_all_data["running_mode"]["level"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# this is very possibly not correct.
|
||||||
|
level = int(level)
|
||||||
|
limit = 1250 + (250 * level)
|
||||||
|
return limit
|
||||||
|
|||||||
@@ -108,10 +108,6 @@ class MinerNetwork:
|
|||||||
# clear cached miners
|
# clear cached miners
|
||||||
MinerFactory().clear_cached_miners()
|
MinerFactory().clear_cached_miners()
|
||||||
|
|
||||||
# create a list of tasks and miner IPs
|
|
||||||
scan_tasks = []
|
|
||||||
miners = []
|
|
||||||
|
|
||||||
limit = asyncio.Semaphore(PyasicSettings().network_scan_threads)
|
limit = asyncio.Semaphore(PyasicSettings().network_scan_threads)
|
||||||
miners = await asyncio.gather(
|
miners = await asyncio.gather(
|
||||||
*[self.ping_and_get_miner(host, limit) for host in local_network.hosts()]
|
*[self.ping_and_get_miner(host, limit) for host in local_network.hosts()]
|
||||||
@@ -140,8 +136,6 @@ class MinerNetwork:
|
|||||||
local_network = self.get_network()
|
local_network = self.get_network()
|
||||||
|
|
||||||
# create a list of scan tasks
|
# create a list of scan tasks
|
||||||
scan_tasks = []
|
|
||||||
|
|
||||||
limit = asyncio.Semaphore(PyasicSettings().network_scan_threads)
|
limit = asyncio.Semaphore(PyasicSettings().network_scan_threads)
|
||||||
miners = asyncio.as_completed(
|
miners = asyncio.as_completed(
|
||||||
[
|
[
|
||||||
@@ -213,14 +207,13 @@ async def ping_miner(
|
|||||||
except asyncio.exceptions.TimeoutError:
|
except asyncio.exceptions.TimeoutError:
|
||||||
# ping failed if we time out
|
# ping failed if we time out
|
||||||
continue
|
continue
|
||||||
except ConnectionRefusedError:
|
except (ConnectionRefusedError, OSError):
|
||||||
# handle for other connection errors
|
# handle for other connection errors
|
||||||
logging.debug(f"{str(ip)}: Connection Refused.")
|
logging.debug(f"{str(ip)}: Connection Refused.")
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
# ping failed, likely with an exception
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning(f"{str(ip)}: {e}")
|
logging.warning(f"{str(ip)}: Ping And Get Miner Exception: {e}")
|
||||||
continue
|
raise ConnectionRefusedError
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -228,8 +221,8 @@ async def ping_and_get_miner(
|
|||||||
ip: ipaddress.ip_address, port=4028
|
ip: ipaddress.ip_address, port=4028
|
||||||
) -> Union[None, AnyMiner]:
|
) -> Union[None, AnyMiner]:
|
||||||
for i in range(PyasicSettings().network_ping_retries):
|
for i in range(PyasicSettings().network_ping_retries):
|
||||||
connection_fut = asyncio.open_connection(str(ip), port)
|
|
||||||
try:
|
try:
|
||||||
|
connection_fut = asyncio.open_connection(str(ip), port)
|
||||||
# get the read and write streams from the connection
|
# get the read and write streams from the connection
|
||||||
reader, writer = await asyncio.wait_for(
|
reader, writer = await asyncio.wait_for(
|
||||||
connection_fut, timeout=PyasicSettings().network_ping_timeout
|
connection_fut, timeout=PyasicSettings().network_ping_timeout
|
||||||
@@ -243,13 +236,11 @@ async def ping_and_get_miner(
|
|||||||
except asyncio.exceptions.TimeoutError:
|
except asyncio.exceptions.TimeoutError:
|
||||||
# ping failed if we time out
|
# ping failed if we time out
|
||||||
continue
|
continue
|
||||||
except ConnectionRefusedError as e:
|
except (ConnectionRefusedError, OSError):
|
||||||
# handle for other connection errors
|
# handle for other connection errors
|
||||||
logging.debug(f"{str(ip)}: Connection Refused.")
|
logging.debug(f"{str(ip)}: Connection Refused.")
|
||||||
raise e
|
raise ConnectionRefusedError
|
||||||
# ping failed, likely with an exception
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning(f"{str(ip)}: Ping And Get Miner Exception: {e}")
|
logging.warning(f"{str(ip)}: Ping And Get Miner Exception: {e}")
|
||||||
raise e
|
raise ConnectionRefusedError
|
||||||
continue
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pyasic"
|
name = "pyasic"
|
||||||
version = "0.28.4"
|
version = "0.29.2"
|
||||||
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
description = "A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH."
|
||||||
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
authors = ["UpstreamData <brett@upstreamdata.ca>"]
|
||||||
repository = "https://github.com/UpstreamData/pyasic"
|
repository = "https://github.com/UpstreamData/pyasic"
|
||||||
|
|||||||
Reference in New Issue
Block a user