From 92b847656e4c44ce07aa361c241a59078d4640f4 Mon Sep 17 00:00:00 2001 From: UpstreamData <75442874+UpstreamData@users.noreply.github.com> Date: Wed, 10 Aug 2022 15:31:42 -0600 Subject: [PATCH] add light functions for btminer, and add a way to reset to admin password for btminers to allow unlocking of priviledged API. --- pyasic/API/btminer.py | 33 ++++++++++++++------- pyasic/miners/_backends/bosminer.py | 5 ++-- pyasic/miners/_backends/btminer.py | 46 +++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/pyasic/API/btminer.py b/pyasic/API/btminer.py index e82b33b3..b77abdd3 100644 --- a/pyasic/API/btminer.py +++ b/pyasic/API/btminer.py @@ -183,7 +183,7 @@ class BTMinerAPI(BaseMinerAPI): pwd: str = PyasicSettings().global_whatsminer_password, ): super().__init__(ip, port) - self.admin_pwd = pwd + self.pwd = pwd self.current_token = None async def send_command( @@ -260,7 +260,7 @@ class BTMinerAPI(BaseMinerAPI): data = await self.send_command("get_token") # encrypt the admin password with the salt - pwd = _crypt(self.admin_pwd, "$1$" + data["Msg"]["salt"] + "$") + pwd = _crypt(self.pwd, "$1$" + data["Msg"]["salt"] + "$") pwd = pwd.split("$") # take the 4th item from the pwd split @@ -437,6 +437,7 @@ class BTMinerAPI(BaseMinerAPI): async def set_led( self, + auto: bool = True, color: str = "red", period: int = 2000, duration: int = 1000, @@ -450,6 +451,7 @@ class BTMinerAPI(BaseMinerAPI): changing the password of the miner using the Whatsminer tool. Parameters: + auto: Whether or not to reset the LED to auto mode. color: The LED color to set, either 'red' or 'green'. period: The flash cycle in ms. duration: LED on time in the cycle in ms. @@ -459,16 +461,19 @@ class BTMinerAPI(BaseMinerAPI): A reply informing of the status of setting the LED. """ - command = { - "cmd": "set_led", - "color": color, - "period": period, - "duration": duration, - "start": start, - } + if not auto: + command = { + "cmd": "set_led", + "color": color, + "period": period, + "duration": duration, + "start": start, + } + else: + command = {"cmd": "set_led", "param": "auto"} token_data = await self.get_token() enc_command = create_privileged_cmd(token_data, command) - return await self.send_command(enc_command) + return await self.send_command(enc_command, ignore_errors=True) async def set_low_power(self) -> dict: """Set low power mode on the miner using the API. @@ -542,6 +547,7 @@ class BTMinerAPI(BaseMinerAPI): A reply informing of the status of setting the password. """ + self.pwd = old_pwd # check if password length is greater than 8 bytes if len(new_pwd.encode("utf-8")) > 8: raise APIError( @@ -551,7 +557,12 @@ class BTMinerAPI(BaseMinerAPI): command = {"cmd": "update_pwd", "old": old_pwd, "new": new_pwd} token_data = await self.get_token() enc_command = create_privileged_cmd(token_data, command) - return await self.send_command(enc_command) + try: + data = await self.send_command(enc_command) + except APIError as e: + raise e + self.pwd = new_pwd + return data async def set_target_freq(self, percent: int) -> dict: """Update the target frequency. diff --git a/pyasic/miners/_backends/bosminer.py b/pyasic/miners/_backends/bosminer.py index c80147a6..70129dd2 100644 --- a/pyasic/miners/_backends/bosminer.py +++ b/pyasic/miners/_backends/bosminer.py @@ -72,11 +72,11 @@ class BOSMiner(BaseMiner): async def fault_light_on(self) -> bool: """Sends command to turn on fault light on the miner.""" logging.debug(f"{self}: Sending fault_light on command.") - self.light = True _ret = await self.send_ssh_command("miner fault_light on") logging.debug(f"{self}: fault_light on command completed.") if isinstance(_ret, str): - return True + self.light = True + return self.light return False async def fault_light_off(self) -> bool: @@ -86,6 +86,7 @@ class BOSMiner(BaseMiner): _ret = await self.send_ssh_command("miner fault_light off") logging.debug(f"{self}: fault_light off command completed.") if isinstance(_ret, str): + self.light = False return True return False diff --git a/pyasic/miners/_backends/btminer.py b/pyasic/miners/_backends/btminer.py index 3cd1f5cb..0d59fe35 100644 --- a/pyasic/miners/_backends/btminer.py +++ b/pyasic/miners/_backends/btminer.py @@ -100,15 +100,57 @@ class BTMiner(BaseMiner): return str(mac).upper() + async def _reset_api_pwd_to_admin(self, pwd: str): + try: + data = await self.api.update_pwd(pwd, "admin") + except APIError: + return False + if data: + if "Code" in data.keys(): + if data["Code"] == 131: + return True + print(data) + return False + async def check_light(self) -> bool: - if not self.light: - self.light = False + data = None + + try: + data = await self.api.get_miner_info() + except APIError: + if not self.light: + self.light = False + if data: + if "Msg" in data.keys(): + if "ledstat" in data["Msg"].keys(): + if not data["Msg"]["ledstat"] == "auto": + self.light = True + if data["Msg"]["ledstat"] == "auto": + self.light = False return self.light async def fault_light_off(self) -> bool: + try: + data = await self.api.set_led(auto=True) + except APIError: + return False + if data: + if "Code" in data.keys(): + if data["Code"] == 131: + self.light = False + return True return False async def fault_light_on(self) -> bool: + try: + data = await self.api.set_led(auto=False) + except APIError: + return False + if data: + if "Code" in data.keys(): + if data["Code"] == 131: + self.light = True + return True return False async def get_errors(self) -> list: