import os import random from threading import Thread from app import espota from app.espota import FLASH, SPIFFS import esptool import serial import wx from app.utils import get_app_data_folder class FwUpdater: update_progress = None currentlyUpdating = False def __init__(self, update_progress, event_cb): self.update_progress = update_progress self.event_cb = event_cb def get_serial_ports(self): ports = serial.tools.list_ports.comports() available_ports = [] for port, desc, hwid in sorted(ports): available_ports.append((port, desc, hwid)) print(f"Port: {port}, Description: {desc}, Hardware ID: {hwid}") return available_ports def run_fs_update(self, address, firmware_file, type): global PROGRESS PROGRESS = True espota.PROGRESS = True global TIMEOUT TIMEOUT = 10 espota.TIMEOUT = 10 espota.serve(address, "0.0.0.0", 3232, random.randint( 10000, 60000), "", firmware_file, type, self.update_progress) wx.CallAfter(self.update_progress, 1) self.currentlyUpdating = False # self.SetStatusText(f"Finished!") def flash_firmware(port, baud, firmware_path): try: # Initialize the serial port serial_port = serial.Serial(port, baud) # Initialize the ESP32ROM with the serial port esp = esptool.ESP32ROM(serial_port) # Connect to the ESP32 esp.connect() # Perform the flashing operation esp.flash_file(firmware_path, offset=0x1000) # Optionally, verify the flash esp.verify_flash(firmware_path, offset=0x1000) print("Firmware flashed successfully!") except esptool.FatalError as e: print(f"Failed to flash firmware: {e}") finally: # Ensure the serial port is closed if serial_port.is_open: serial_port.close() def start_firmware_update(self, release_name, address, hw_rev): # self.SetStatusText(f"Starting firmware update") hw_rev_to_model = { "REV_B_EPD_2_13": "btclock_rev_b_213epd", "REV_V8_EPD_2_13": "btclock_v8_213epd", "REV_A_EPD_2_9": "lolin_s3_mini_29epd" } model_name = hw_rev_to_model.get(hw_rev, "lolin_s3_mini_213epd") local_filename = f"{get_app_data_folder()}/{ release_name}_{model_name}_firmware.bin" self.updatingName = address self.currentlyUpdating = True if self.event_cb is not None: self.event_cb("Starting Firmware update") if os.path.exists(os.path.abspath(local_filename)): thread = Thread(target=self.run_fs_update, args=( address, os.path.abspath(local_filename), FLASH)) thread.start() def start_fs_update(self, release_name, address): # Path to the firmware file local_filename = f"{get_app_data_folder()}/{release_name}_littlefs.bin" self.updatingName = address self.currentlyUpdating = True if self.event_cb is not None: self.event_cb("Starting WebUI update") if os.path.exists(os.path.abspath(local_filename)): thread = Thread(target=self.run_fs_update, args=( address, os.path.abspath(local_filename), SPIFFS)) thread.start()