58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
import os
|
||
import time
|
||
import sys
|
||
|
||
|
||
def _estimate_fw_timeout_seconds(conn, total_size: int) -> float:
|
||
base = float(getattr(conn, "timeout", 5.0))
|
||
erase_budget = 8.0
|
||
stream_and_write_budget = total_size / (25.0 * 1024.0)
|
||
return max(base, erase_budget + stream_and_write_budget)
|
||
|
||
|
||
def execute(conn, source: str):
|
||
if not os.path.isfile(source):
|
||
raise FileNotFoundError(f"Firmware-Datei nicht gefunden: {source}")
|
||
|
||
with open(source, "rb") as f:
|
||
data = f.read()
|
||
|
||
total_size = len(data)
|
||
if total_size == 0:
|
||
raise ValueError("Firmware-Datei ist leer.")
|
||
|
||
print(f"Sende 🧩 Firmware ({total_size / 1024:.1f} KB) -> secondary slot")
|
||
fw_timeout = _estimate_fw_timeout_seconds(conn, total_size)
|
||
print(f" Timeout fw_put: {fw_timeout:.1f}s")
|
||
print(" Phase 1/3: Lösche secondary slot und initialisiere Flash...")
|
||
|
||
start_time = time.monotonic()
|
||
last_ui_update = start_time
|
||
transfer_started = False
|
||
|
||
def progress_handler(chunk_len, sent_file, total_file):
|
||
nonlocal last_ui_update, transfer_started
|
||
if not transfer_started:
|
||
transfer_started = True
|
||
print(" Phase 2/3: Übertrage Firmware...")
|
||
now = time.monotonic()
|
||
if now - last_ui_update < 0.2 and sent_file < total_file:
|
||
return
|
||
last_ui_update = now
|
||
|
||
elapsed = now - start_time
|
||
speed = (sent_file / 1024.0) / elapsed if elapsed > 0 else 0.0
|
||
perc = (sent_file / total_file) * 100.0 if total_file > 0 else 100.0
|
||
eta_sec = ((total_file - sent_file) / (sent_file / elapsed)) if sent_file > 0 and elapsed > 0 else 0.0
|
||
eta_str = f"{int(eta_sec // 60):02d}:{int(eta_sec % 60):02d}"
|
||
|
||
sys.stdout.write(
|
||
f"\r \033[90mProg: {perc:3.0f}% | {speed:6.1f} KB/s | ETA: {eta_str}\033[0m"
|
||
)
|
||
sys.stdout.flush()
|
||
|
||
crc32 = conn.fw_put_data(data, timeout=fw_timeout, progress_callback=progress_handler)
|
||
print("\n Phase 3/3: Finalisiere und warte auf Geräte-ACK...")
|
||
print(f"\r \033[32mFertig: Firmware übertragen (CRC32: 0x{crc32:08x}).{' ' * 16}\033[0m")
|
||
print("ℹ️ Nächste Schritte: reboot -> testen -> confirm")
|