Files
StandGUI/myscript.py
s.terehin 56bae8818e Обновить myscript.py
Добавлена фича отправки пароля в телеграмм
2025-10-22 14:56:00 +03:00

814 lines
39 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
import tkinter as tk
from tkinter import messagebox, ttk
import subprocess
import sys
import os
import re
import glob
from datetime import datetime
import time
import serial
import telebot
import threading
import logging
class MainApp:
def __init__(self, root):
self.root = root
self.root.title("Мое Приложение")
self.root.geometry("900x900")
self.root.configure(bg='#f0f0f0')
# Add these class variables to MainApp.__init__ after self.root.configure(bg='#f0f0f0')
self.telegram_bot_token = "5481440980:AAF1oPtuwS9NCVqcNmV2G80x9r77w1NUhEg" # Replace with your bot token from BotFather
self.telegram_user_id = None # Replace with the Telegram user ID to receive messages
self.bot = None
# Позиционируем окно по левому краю экрана
self.position_window_left()
# Увеличим шрифты для лучшей видимости на 7-дюймовом мониторе
self.big_font = ('Arial', 24)
self.medium_font = ('Arial', 20)
self.small_font = ('Arial', 16)
self.create_widgets()
self.start_telegram_bot()
# Автоматически открываем Minicom при запуске
self.root.after(1000, self.open_minicom) # Задержка 1 секунда перед открытием Minicom
def position_window_left(self):
"""Позиционирует окно по левому краю экрана"""
# Получаем размеры экрана
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
# Получаем размеры окна
window_width = 900
window_height = 900
# Вычисляем позицию для левого края
x_position = 0
y_position = (screen_height - window_height) // 2
# Устанавливаем позицию окна
self.root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
def create_widgets(self):
# Заголовок
title_label = tk.Label(
self.root,
text="Главное меню",
font=('Arial', 24, 'bold'),
bg='#f0f0f0',
fg='#333333'
)
title_label.pack(pady=20)
# Кнопка Авто STM32
self.auto_stm32_btn = tk.Button(
self.root,
text="Тестовое ПО",
font=self.big_font,
bg='#4CAF50',
fg='white',
width=15,
height=2,
command=lambda: self.auto_mode('test')
)
self.auto_stm32_btn.pack(pady=10)
# Кнопка Авто ESP32
self.auto_esp32_btn = tk.Button(
self.root,
text="Рабочее ПО",
font=self.big_font,
bg='#2196F3',
fg='white',
width=15,
height=2,
command=lambda: self.auto_mode('work')
)
self.auto_esp32_btn.pack(pady=10)
# Кнопка Minicom
self.minicom_btn = tk.Button(
self.root,
text="Получить пароль",
font=self.big_font,
bg='#FF9800',
fg='white',
width=15,
height=2,
command=self.get_password
)
self.minicom_btn.pack(pady=10)
# Кнопка Выход
self.exit_btn = tk.Button(
self.root,
text="Выход",
font=self.big_font,
bg='#f44336',
fg='white',
width=15,
height=2,
command=self.exit_app
)
self.exit_btn.pack(pady=10)
# Область для лога
log_frame = tk.Frame(self.root, bg='#f0f0f0')
log_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
tk.Label(
log_frame,
text="Лог выполнения:",
font=self.medium_font,
bg='#f0f0f0',
fg='#333333'
).pack(anchor=tk.W)
# Текстовое поле для лога с прокруткой
log_container = tk.Frame(log_frame)
log_container.pack(fill=tk.BOTH, expand=True, pady=5)
self.log_text = tk.Text(
log_container,
height=12,
font=self.small_font,
bg='#2c3e50',
fg='#ecf0f1',
insertbackground='white',
wrap=tk.WORD
)
scrollbar = tk.Scrollbar(log_container, orient=tk.VERTICAL, command=self.log_text.yview)
self.log_text.configure(yscrollcommand=scrollbar.set)
self.log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# Статус бар
self.status_var = tk.StringVar()
self.status_var.set("Готов к работе")
status_bar = tk.Label(
self.root,
textvariable=self.status_var,
font=self.medium_font,
bg='#dddddd',
relief=tk.SUNKEN,
anchor=tk.W
)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# Добавляем начальное сообщение в лог
self.add_to_log("✅ Приложение запущено и готово к работе")
self.add_to_log("📐 Окно позиционировано по левому краю (900x900)")
def start_telegram_bot(self):
"""Запускает Telegram бота в фоновом потоке"""
try:
self.bot = telebot.TeleBot(self.telegram_bot_token)
# Обработчик команды /edison
@self.bot.message_handler(commands=['edison'])
def handle_edison(message):
self.telegram_chat_id = message.chat.id
response = (
f"🔧 Режим Edison активирован!\n"
f"📋 Ваш ID: {message.chat.id}\n"
f"✅ Теперь я буду присылать сюда все пароли"
)
self.bot.send_message(message.chat.id, response)
print(f"✅ Chat ID сохранен: {message.chat.id}")
self.add_to_log(f"✅ Telegram: получен chat_id {message.chat.id}")
# Запускаем бота в отдельном потоке
bot_thread = threading.Thread(target=self.bot.polling, daemon=True)
bot_thread.start()
print("✅ Telegram бот запущен. Ожидаю команду /edison")
self.add_to_log("✅ Telegram бот запущен. Отправьте /edison в бот")
except Exception as e:
print(f"❌ Ошибка запуска бота: {e}")
self.add_to_log(f"❌ Ошибка запуска Telegram бота: {e}")
def send_telegram_message(self, message):
"""Отправляет сообщение в Telegram"""
try:
if self.bot and self.telegram_chat_id:
self.bot.send_message(self.telegram_chat_id, message)
print(f"✅ Сообщение отправлено: {message}")
return True
else:
if not self.telegram_chat_id:
print("⚠️ Chat ID не установлен. Отправьте /edison боту")
self.add_to_log("⚠️ Telegram: chat_id не установлен. Отправьте /edison")
return False
except Exception as e:
print(f"❌ Ошибка отправки: {e}")
self.add_to_log(f"❌ Ошибка отправки в Telegram: {e}")
return False
def get_password(self):
"""Получает пароль от устройства"""
self.add_to_log("🔑 Запуск процесса получения пароля...")
self.status_var.set("Получение пароля...")
try:
# Прошивка STM32 с firmware для получения UID
self.add_to_log("🔍 Прошивка STM32 для получения UID...")
stm32_firmware = os.path.expanduser("~/fw/getuid/STM32_GET_UID.bin")
if os.path.exists(stm32_firmware):
# Стираем флеш-память STM32
self.add_to_log("🧹 Стирание флеш-памяти STM32...")
erase_result = subprocess.run([
'st-flash', 'erase'
], capture_output=True, text=True, timeout=30)
if erase_result.returncode != 0:
self.add_to_log(f"❌ Ошибка стирания STM32: {erase_result.stderr}")
return False
# Прошивка STM32
# Прошивка ESP32
self.add_to_log("📥 Прошивка ESP32 для получения пароля...")
port = "/dev/ttyUSB0"
# Файлы для ESP32
bootloader_path = os.path.expanduser("~/fw/getuid/bootloader.bin")
firmware_path = os.path.expanduser("~/fw/getuid/ET_22KW_1.0b.bin")
partition_path = os.path.expanduser("~/fw/getuid/partition-table.bin")
www_path = os.path.expanduser("~/fw/getuid/www.bin")
if not all([os.path.exists(p) for p in [bootloader_path, firmware_path, partition_path, www_path]]):
self.add_to_log("Не все файлы прошивки GetUID найдены")
return False
# Стираем флеш-память ESP32
self.add_to_log("🧹 Стирание флеш-памяти ESP32...")
esp_erase_result = subprocess.run([
'esptool.py', '--chip', 'esp32', '--port', port, 'erase_flash'
], capture_output=True, text=True, timeout=60)
time.sleep(60) # Ждем после стирания
# Прошиваем ESP32
flash_command = [
'esptool.py', '--chip', 'esp32', '--port', port, '--baud', '460800',
'write_flash', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect',
'0x1000', bootloader_path,
'0x10000', firmware_path,
'0x8000', partition_path,
'0x210000', www_path
]
self.add_to_log(f"🔧 Команда прошивки: {' '.join(flash_command)}")
flash_result = subprocess.run(flash_command, capture_output=True, text=True, timeout=180)
if flash_result.returncode != 0:
self.add_to_log(f"❌ Ошибка прошивки ESP32: {flash_result.stderr}")
return False
self.add_to_log("📥 Прошивка STM32 специальной прошивкой...")
flash_result = subprocess.run([
'st-flash', '--reset', 'write',
stm32_firmware, '0x08000000'
], capture_output=True, text=True, timeout=30)
if flash_result.returncode != 0:
self.add_to_log(f"❌ Ошибка прошивки STM32: {flash_result.stderr}")
return False
# Перезагрузка устройств
self.add_to_log("🔄 Перезагрузка устройств...")
# Перезагрузка ESP32
subprocess.run(['esptool.py', '--port', port, 'run'],
capture_output=True, text=True, timeout=20)
time.sleep(5)
# Перезагрузка STM32
subprocess.run(['st-flash', 'reset'],
capture_output=True, text=True, timeout=20)
time.sleep(5)
# Повторяем перезагрузку для надежности
self.add_to_log("🔄 Повторная перезагрузка устройств...")
subprocess.run(['esptool.py', '--port', port, 'run'],
capture_output=True, text=True, timeout=20)
time.sleep(5)
subprocess.run(['st-flash', 'reset'],
capture_output=True, text=True, timeout=20)
# Чтение данных с COM-порта
self.add_to_log("📋 Чтение данных с порта...")
try:
with serial.Serial(port, 115200, timeout=20) as ser:
time.sleep(2)
data = ser.read(10000)
received_data = data.decode(errors='ignore')
# self.add_to_log(f"📟 Полученные данные: {received_data}")
# Updated pattern to match "Hash:: XXXXXXXXXXXX" format
import re
password_match = re.search(r'Hash:: ([A-Za-z0-9]+)', received_data)
if password_match:
password = password_match.group(1)
self.add_to_log(f"🔑 Найден пароль: {password}")
self.status_var.set(f"Пароль: {password}")
success = self.send_telegram_message(f"🔐 Новый пароль получен: {password}")
if success:
self.add_to_log("✅ Пароль отправлен в Telegram")
else:
self.add_to_log("Не удалось отправить пароль в Telegram")
return password
else:
self.add_to_log("❌ Пароль не найден в полученных данных")
return None
except serial.SerialException as e:
self.add_to_log(f"❌ Ошибка чтения COM-порта: {str(e)}")
return None
else:
self.add_to_log(f"❌ Файл прошивки STM32 для получения UID не найден: {stm32_firmware}")
return None
except Exception as e:
self.add_to_log(f"❌ Произошла ошибка при получении пароля: {str(e)}")
self.status_var.set("Ошибка получения пароля")
return None
def open_minicom(self):
"""Открывает minicom в отдельном терминале"""
try:
self.status_var.set("Запуск minicom...")
self.add_to_log("🔄 Запускаю minicom...")
# Автоматически находим порт
ports = glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')
if ports:
port = "/dev/ttyUSB1"
self.add_to_log(f"🔌 Найден порт: {port}")
subprocess.Popen([
'lxterminal',
'--geometry=80x60',
'-e',
f'bash -c "minicom -D {port} -b 115200; exec bash"'
])
self.status_var.set("Minicom запущен")
self.add_to_log(f"✅ Minicom запущен на {port}")
else:
self.add_to_log("❌ COM-порты не найдены")
except Exception as e:
self.status_var.set("Ошибка запуска minicom")
self.add_to_log(f"❌ Ошибка запуска minicom: {str(e)}")
def add_to_log(self, message):
"""Добавляет сообщение в лог с временной меткой"""
timestamp = datetime.now().strftime("%H:%M:%S")
formatted_message = f"[{timestamp}] {message}\n"
self.log_text.insert(tk.END, formatted_message)
self.log_text.see(tk.END)
self.root.update_idletasks()
def find_serial_ports(self):
"""Поиск доступных COM-портов"""
ports = []
# Поиск на Linux
if sys.platform.startswith('linux'):
ports = glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*')
# Поиск на Windows
elif sys.platform.startswith('win'):
ports = [f"COM{i}" for i in range(1, 256)]
# Поиск на MacOS
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
available_ports = []
for port in ports:
if sys.platform.startswith('win'):
# На Windows просто проверяем существование
if os.path.exists(port):
available_ports.append(port)
else:
# На Linux/Mac проверяем доступность
try:
if os.path.exists(port) and os.access(port, os.R_OK):
available_ports.append(port)
except:
pass
return available_ports
def check_stm32_connection(self):
"""Проверка подключения STM32"""
try:
result = subprocess.run(['st-info', '--chipid'], capture_output=True, text=True, timeout=10)
chip_id = None
# Ищем hex число в выводе
match = re.search(r'0x[0-9A-Fa-f]+', result.stdout + result.stderr)
if match:
chip_id = match.group(0)
if chip_id and chip_id != "0x0000":
return True, chip_id
else:
return False, None
except Exception as e:
return False, None
def check_esp32_connection(self):
"""Проверка подключения ESP32"""
try:
# Ищем порт ESP32
ports = self.find_serial_ports()
if not ports:
return False, None, None
port = "/dev/ttyUSB0" # Берем первый доступный порт
# Пробуем получить информацию о чипе ESP32
result = subprocess.run([
'esptool.py', '--port', port, 'chip_id'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
return True, port, "ESP32 обнаружен"
else:
return False, port, None
except Exception as e:
return False, None, str(e)
def auto_mode(self, mcu_type):
"""Автоматический режим для STM32 или ESP32"""
self.status_var.set(f"Режим Авто {mcu_type.upper()} активирован")
self.add_to_log(f"🔄 Запуск автоматического режима для {mcu_type.upper()}...")
if mcu_type == 'test':
self.auto_mode_erase_stm32()
time.sleep(3)
self.auto_mode_test_esp32()
time.sleep(3)
self.auto_mode_test_stm32()
elif mcu_type == 'work':
self.auto_mode_work()
def auto_mode_erase_stm32(self):
"""Тестовое ПО"""
flash_success = False
try:
# Проверка подключения микроконтроллера
self.add_to_log("🔍 Проверка подключения STM32...")
connected, chip_id = self.check_stm32_connection()
if connected:
self.status_var.set(f"✅ STM32 подключен, Chip ID: {chip_id}")
self.add_to_log(f"✅ STM32 подключен, Chip ID: {chip_id}")
# Проверка файла прошивки
self.add_to_log("🔍 Очистка памяти STM32...")
flash_result = subprocess.run([
'st-flash', 'erase'
], capture_output=True, text=True, timeout=60)
if flash_result.returncode == 0:
self.status_var.set("✅ Очистка STM32 завершена успешно!")
self.add_to_log("✅ Очистка STM32 завершена успешно!")
flash_success = True
else:
self.status_var.set("❌ Ошибка очистки STM32")
self.add_to_log(f"❌ Ошибка очистки STM32: {flash_result.stderr}")
else:
self.status_var.set("❌ STM32 не подключен")
self.add_to_log("❌ STM32 не подключен")
except subprocess.TimeoutExpired:
self.status_var.set("❌ Таймаут операции STM32")
self.add_to_log("❌ Таймаут операции STM32!")
except Exception as e:
self.status_var.set("❌ Ошибка выполнения STM32")
self.add_to_log(f"❌ Произошла ошибка STM32: {str(e)}")
self.add_to_log("🔚 Очистка STM32 завершена")
def auto_mode_test_stm32(self):
"""Тестовое ПО"""
flash_success = False
try:
# Проверка подключения микроконтроллера
self.add_to_log("🔍 Проверка подключения STM32...")
connected, chip_id = self.check_stm32_connection()
if connected:
self.status_var.set(f"✅ STM32 подключен, Chip ID: {chip_id}")
self.add_to_log(f"✅ STM32 подключен, Chip ID: {chip_id}")
# Проверка файла прошивки
self.add_to_log("🔍 Поиск файла прошивки STM32...")
firmware_path = os.path.expanduser("~/fw/TestStand_FW_STM32.bin")
if os.path.exists(firmware_path):
file_size = os.path.getsize(firmware_path)
self.status_var.set("✅ Файл прошивки STM32 найден")
self.add_to_log(f"✅ Файл прошивки найден: TestStand_FW_STM32.bin ({file_size} байт)")
# Прошивка микроконтроллера
self.status_var.set("🔄 Идет прошивка STM32...")
self.add_to_log("🔄 Начинаю прошивку STM32...")
flash_result = subprocess.run([
'st-flash', '--reset', 'write',
firmware_path, '0x08000000'
], capture_output=True, text=True, timeout=60)
if flash_result.returncode == 0:
self.status_var.set("✅ Прошивка STM32 завершена успешно!")
self.add_to_log("✅ Прошивка STM32 завершена успешно!")
flash_success = True
else:
self.status_var.set("❌ Ошибка прошивки STM32")
self.add_to_log(f"❌ Ошибка прошивки STM32: {flash_result.stderr}")
else:
self.status_var.set("❌ Файл прошивки STM32 не найден")
self.add_to_log("❌ Файл прошивки STM32 не найден")
self.show_available_files()
else:
self.status_var.set("❌ STM32 не подключен")
self.add_to_log("❌ STM32 не подключен")
except subprocess.TimeoutExpired:
self.status_var.set("❌ Таймаут операции STM32")
self.add_to_log("❌ Таймаут операции STM32!")
except Exception as e:
self.status_var.set("❌ Ошибка выполнения STM32")
self.add_to_log(f"❌ Произошла ошибка STM32: {str(e)}")
self.add_to_log("🔚 Автоматический режим STM32 завершен")
def auto_mode_test_esp32(self):
try:
# Проверка подключения микроконтроллера
self.add_to_log("🔍 Проверка подключения ESP32...")
connected, port, chip_info = self.check_esp32_connection()
port = "/dev/ttyUSB0"
if connected and port:
self.status_var.set(f"✅ ESP32 подключен на {port}")
self.add_to_log(f"✅ ESP32 подключен на {port}")
if chip_info:
self.add_to_log(f" {chip_info}")
# Проверка файлов прошивки ESP32
self.add_to_log("🔍 Поиск файлов прошивки ESP32...")
bootloader_path = os.path.expanduser("~/fw/bootloader.bin")
firmware_path = os.path.expanduser("~/fw/TestStand_FW_ESP32.bin")
partition_path = os.path.expanduser("~/fw/partition-table.bin")
files_exist = all([
os.path.exists(bootloader_path),
os.path.exists(firmware_path),
os.path.exists(partition_path)
])
if files_exist:
self.status_var.set("✅ Файлы прошивки ESP32 найдены")
self.add_to_log("Все файлы прошивки ESP32 найдены:")
self.add_to_log(f" - bootloader.bin ({os.path.getsize(bootloader_path)} байт)")
self.add_to_log(f" - TestStand_FW_ESP32.bin ({os.path.getsize(firmware_path)} байт)")
self.add_to_log(f" - partition-table.bin ({os.path.getsize(partition_path)} байт)")
# Прошивка ESP32
self.status_var.set("🔄 Идет прошивка ESP32...")
self.add_to_log("🔄 Начинаю прошивку ESP32...")
flash_command = [
'esptool.py', '--chip', 'esp32', '--port', port, '--baud', '576000',
'write_flash', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect',
'0x1000', bootloader_path,
'0x10000', firmware_path,
'0x8000', partition_path
]
self.add_to_log(f"🔧 Команда прошивки: {' '.join(flash_command)}")
flash_result = subprocess.run(flash_command, capture_output=True, text=True, timeout=120)
if flash_result.returncode == 0:
self.status_var.set("✅ Прошивка ESP32 завершена успешно!")
self.add_to_log("✅ Прошивка ESP32 завершена успешно!")
flash_success = True
else:
self.status_var.set("❌ Ошибка прошивки ESP32")
self.add_to_log(f"❌ Ошибка прошивки ESP32: {flash_result.stderr}")
else:
self.status_var.set("Не все файлы прошивки ESP32 найдены")
self.add_to_log("Не все файлы прошивки ESP32 найдены")
self.show_available_files()
else:
self.status_var.set("❌ ESP32 не подключен")
self.add_to_log("❌ ESP32 не подключен или порт не найден")
except subprocess.TimeoutExpired:
self.status_var.set("❌ Таймаут операции ESP32")
self.add_to_log("❌ Таймаут операции ESP32!")
except Exception as e:
self.status_var.set("❌ Ошибка выполнения ESP32")
self.add_to_log(f"❌ Произошла ошибка ESP32: {str(e)}")
self.add_to_log("🔚 Автоматический режим ESP32 завершен")
def auto_mode_work(self):
"""Рабочее ПО"""
flash_success = False
try:
# Проверка подключения микроконтроллера
self.add_to_log("🔍 Проверка подключения STM32...")
connected, chip_id = self.check_stm32_connection()
if connected:
self.status_var.set(f"✅ STM32 подключен, Chip ID: {chip_id}")
self.add_to_log(f"✅ STM32 подключен, Chip ID: {chip_id}")
# Проверка файла прошивки
self.add_to_log("🔍 Поиск файла прошивки STM32...")
firmware_path = os.path.expanduser("~/fw/w/STM_2.08_NO_PROTECTION.bin")
if os.path.exists(firmware_path):
file_size = os.path.getsize(firmware_path)
self.status_var.set("✅ Файл прошивки STM32 найден")
self.add_to_log(f"✅ Файл прошивки найден: TestStand_FW_STM32.bin ({file_size} байт)")
# Прошивка микроконтроллера
self.status_var.set("🔄 Идет прошивка STM32...")
self.add_to_log("🔄 Начинаю прошивку STM32...")
flash_result = subprocess.run([
'st-flash', '--reset', 'write',
firmware_path, '0x08000000'
], capture_output=True, text=True, timeout=30)
if flash_result.returncode == 0:
self.status_var.set("✅ Прошивка STM32 завершена успешно!")
self.add_to_log("✅ Прошивка STM32 завершена успешно!")
flash_success = True
else:
self.status_var.set("❌ Ошибка прошивки STM32")
self.add_to_log(f"❌ Ошибка прошивки STM32: {flash_result.stderr}")
else:
self.status_var.set("❌ Файл прошивки STM32 не найден")
self.add_to_log("❌ Файл прошивки STM32 не найден")
self.show_available_files()
else:
self.status_var.set("❌ STM32 не подключен")
self.add_to_log("❌ STM32 не подключен")
except subprocess.TimeoutExpired:
self.status_var.set("❌ Таймаут операции STM32")
self.add_to_log("❌ Таймаут операции STM32!")
except Exception as e:
self.status_var.set("❌ Ошибка выполнения STM32")
self.add_to_log(f"❌ Произошла ошибка STM32: {str(e)}")
self.add_to_log("🔚 Автоматический режим STM32 завершен")
"""Автоматический режим для ESP32"""
flash_success = False
try:
# Проверка подключения микроконтроллера
self.add_to_log("🔍 Проверка подключения ESP32...")
connected, port, chip_info = self.check_esp32_connection()
if connected and port:
self.status_var.set(f"✅ ESP32 подключен на {port}")
self.add_to_log(f"✅ ESP32 подключен на {port}")
if chip_info:
self.add_to_log(f" {chip_info}")
# Проверка файлов прошивки ESP32
self.add_to_log("🔍 Поиск файлов прошивки ESP32...")
bootloader_path = os.path.expanduser("~/fw/w/bootloader.bin")
firmware_path = os.path.expanduser("~/fw/w/ET_22KW_1.0b.bin")
partition_path = os.path.expanduser("~/fw/w/partition-table.bin")
www_path = os.path.expanduser("~/fw/w/www.bin")
files_exist = all([
os.path.exists(bootloader_path),
os.path.exists(firmware_path),
os.path.exists(partition_path),
os.path.exists(www_path)
])
if files_exist:
self.status_var.set("✅ Файлы прошивки ESP32 найдены")
self.add_to_log("Все файлы прошивки ESP32 найдены:")
self.add_to_log(f" - bootloader.bin ({os.path.getsize(bootloader_path)} байт)")
self.add_to_log(f" - TestStand_FW_ESP32.bin ({os.path.getsize(firmware_path)} байт)")
self.add_to_log(f" - partition-table.bin ({os.path.getsize(partition_path)} байт)")
self.add_to_log(f" - www.bin ({os.path.getsize(www_path)} байт)")
# Прошивка ESP32
self.status_var.set("🔄 Идет прошивка ESP32...")
self.add_to_log("🔄 Начинаю прошивку ESP32...")
flash_command = [
'esptool.py', '--chip', 'esp32', '--port', port, '--baud', '576000',
'write_flash', '--flash_mode', 'dio', '--flash_freq', '40m', '--flash_size', 'detect',
'0x1000', bootloader_path,
'0x10000', firmware_path,
'0x8000', partition_path,
'0x210000', www_path
]
self.add_to_log(f"🔧 Команда прошивки: {' '.join(flash_command)}")
flash_result = subprocess.run(flash_command, capture_output=True, text=True, timeout=120)
if flash_result.returncode == 0:
self.status_var.set("✅ Прошивка ESP32 завершена успешно!")
self.add_to_log("✅ Прошивка ESP32 завершена успешно!")
flash_success = True
else:
self.status_var.set("❌ Ошибка прошивки ESP32")
self.add_to_log(f"❌ Ошибка прошивки ESP32: {flash_result.stderr}")
else:
self.status_var.set("Не все файлы прошивки ESP32 найдены")
self.add_to_log("Не все файлы прошивки ESP32 найдены")
self.show_available_files()
else:
self.status_var.set("❌ ESP32 не подключен")
self.add_to_log("❌ ESP32 не подключен или порт не найден")
except subprocess.TimeoutExpired:
self.status_var.set("❌ Таймаут операции ESP32")
self.add_to_log("❌ Таймаут операции ESP32!")
except Exception as e:
self.status_var.set("❌ Ошибка выполнения ESP32")
self.add_to_log(f"❌ Произошла ошибка ESP32: {str(e)}")
self.add_to_log("🔚 Автоматический режим ESP32 завершен")
def show_available_files(self):
"""Показывает доступные файлы в папке fw"""
fw_dir = os.path.expanduser("~/fw")
if os.path.exists(fw_dir):
files = os.listdir(fw_dir)
bin_files = [f for f in files if f.endswith('.bin')]
if bin_files:
self.add_to_log("📁 Доступные файлы в папке fw:")
for file in bin_files:
self.add_to_log(f" - {file}")
else:
self.add_to_log("📁 В папке fw нет .bin файлов")
else:
self.add_to_log("📁 Папка fw не существует")
def exit_app(self):
if messagebox.askyesno("Выход", "Вы уверены, что хотите выйти?"):
self.status_var.set("Завершение работы...")
self.add_to_log("🔴 Приложение завершает работу...")
self.root.quit()
sys.exit()
def main():
try:
root = tk.Tk()
app = MainApp(root)
root.mainloop()
except KeyboardInterrupt:
print("\nПриложение завершено")
except Exception as e:
print(f"Ошибка: {e}")
messagebox.showerror("Ошибка", f"Произошла ошибка: {e}")
if __name__ == "__main__":
main()