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. -
# ------------------------------------------------------------------------------
import logging
import aiofiles
import hashlib
import aiohttp
from pathlib import Path
from typing import List, Optional
@@ -456,68 +452,16 @@ class ePIC(ePICFirmware):
except LookupError:
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.
Args:
file (Path): The local file path of the firmware to be uploaded.
keepsettings (bool): Whether to keep the current settings after the update.
password (str): The password for authentication.
file (Path | str): The local file path of the firmware to be uploaded.
keep_settings (bool): Whether to keep the current settings after the update.
Returns:
str: Confirmation message after upgrading the firmware.
bool: Whether the firmware update succeeded.
"""
try:
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
return await self.web.system_update(file=file, keep_settings=keep_settings)

View File

@@ -19,6 +19,10 @@ import json
from typing import Any
import httpx
import aiofiles
import aiohttp
import hashlib
from pathlib import Path
from pyasic import settings
from pyasic.errors import APIError
@@ -46,6 +50,14 @@ class ePICWebAPI(BaseWebAPI):
async with httpx.AsyncClient(transport=settings.transport()) as client:
for retry_cnt in range(settings.get("get_data_retries", 1)):
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:
response = await client.post(
f"http://{self.ip}:{self.port}/{command}",
@@ -135,3 +147,22 @@ class ePICWebAPI(BaseWebAPI):
async def capabilities(self) -> dict:
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)