Added checksum validation and command handling

This commit is contained in:
1e9abhi1e10
2024-07-03 08:43:22 +05:30
parent bd9592c19c
commit 092126bded
2 changed files with 37 additions and 62 deletions

View File

@@ -14,10 +14,6 @@
# limitations under the License. - # limitations under the License. -
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
import logging
import aiofiles
import hashlib
import aiohttp
from pathlib import Path from pathlib import Path
from typing import List, Optional from typing import List, Optional
@@ -456,68 +452,16 @@ class ePIC(ePICFirmware):
except LookupError: except LookupError:
pass pass
async def upgrade_firmware(self, file: Path, keepsettings: bool, password: str): async def upgrade_firmware(self, file: Path | str, keep_settings: bool = True) -> bool:
""" """
Upgrade the firmware of the ePIC miner device. Upgrade the firmware of the ePIC miner device.
Args: Args:
file (Path): The local file path of the firmware to be uploaded. file (Path | str): The local file path of the firmware to be uploaded.
keepsettings (bool): Whether to keep the current settings after the update. keep_settings (bool): Whether to keep the current settings after the update.
password (str): The password for authentication.
Returns: Returns:
str: Confirmation message after upgrading the firmware. bool: Whether the firmware update succeeded.
""" """
try: return await self.web.system_update(file=file, keep_settings=keep_settings)
logging.info("Starting firmware upgrade process for ePIC miner.")
if not file:
raise ValueError("File location must be provided for firmware upgrade.")
# calculate the SHA256 checksum of the firmware file
sha256_hash = hashlib.sha256()
async with aiofiles.open(file, "rb") as f:
while chunk := await f.read(8192):
sha256_hash.update(chunk)
checksum = sha256_hash.hexdigest()
# prepare the multipart/form-data request
form_data = aiohttp.FormData()
form_data.add_field('checksum', checksum)
form_data.add_field('keepsettings', str(keepsettings).lower())
form_data.add_field('password', password)
form_data.add_field('update.zip', open(file, 'rb'), filename='update.zip')
# Send the POST request to the ePIC miner device
async with self.web.post(f"http://{self.ip}:{self.port}/systemupdate", data=form_data) as response:
if response.status == 200:
result = await response.json()
if result.get("result"):
logging.info("Firmware upgrade process completed successfully for ePIC miner.")
return "Firmware upgrade completed successfully."
else:
error = result.get("error", "Unknown error")
logging.error(f"Firmware upgrade failed: {error}")
raise Exception(f"Firmware upgrade failed: {error}")
else:
logging.error(f"Firmware upgrade failed with status code: {response.status}")
raise Exception(f"Firmware upgrade failed with status code: {response.status}")
except FileNotFoundError as e:
logging.error(f"File not found during the firmware upgrade process: {e}")
raise
except ValueError as e:
logging.error(
f"Validation error occurred during the firmware upgrade process: {e}"
)
raise
except OSError as e:
logging.error(f"OS error occurred during the firmware upgrade process: {e}")
raise
except Exception as e:
logging.error(
f"An unexpected error occurred during the firmware upgrade process: {e}",
exc_info=True,
)
raise

View File

@@ -19,6 +19,10 @@ import json
from typing import Any from typing import Any
import httpx import httpx
import aiofiles
import aiohttp
import hashlib
from pathlib import Path
from pyasic import settings from pyasic import settings
from pyasic.errors import APIError from pyasic.errors import APIError
@@ -46,6 +50,14 @@ class ePICWebAPI(BaseWebAPI):
async with httpx.AsyncClient(transport=settings.transport()) as client: async with httpx.AsyncClient(transport=settings.transport()) as client:
for retry_cnt in range(settings.get("get_data_retries", 1)): for retry_cnt in range(settings.get("get_data_retries", 1)):
try: try:
if parameters.get("form") is not None:
form_data = parameters["form"]
form_data.add_field('password', self.pwd)
response = await client.post(
f"http://{self.ip}:{self.port}/{command}",
timeout=5,
data=form_data,
)
if post: if post:
response = await client.post( response = await client.post(
f"http://{self.ip}:{self.port}/{command}", f"http://{self.ip}:{self.port}/{command}",
@@ -135,3 +147,22 @@ class ePICWebAPI(BaseWebAPI):
async def capabilities(self) -> dict: async def capabilities(self) -> dict:
return await self.send_command("capabilities") return await self.send_command("capabilities")
async def system_update(self, file: Path | str, keep_settings: bool = True):
"""Perform a system update by uploading a firmware file and sending a
command to initiate the update."""
# calculate the SHA256 checksum of the firmware file
sha256_hash = hashlib.sha256()
async with aiofiles.open(str(file), "rb") as f:
while chunk := await f.read(8192):
sha256_hash.update(chunk)
checksum = sha256_hash.hexdigest()
# prepare the multipart/form-data request
form_data = aiohttp.FormData()
form_data.add_field('checksum', checksum)
form_data.add_field('keepsettings', str(keep_settings).lower())
form_data.add_field('update.zip', open(file, 'rb'), filename='update.zip')
await self.send_command("systemupdate", form=form_data)