diff --git a/myscript.py b/myscript.py new file mode 100644 index 0000000..8bd91c2 --- /dev/null +++ b/myscript.py @@ -0,0 +1,622 @@ +#!/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 + +class MainApp: + def __init__(self, root): + self.root = root + self.root.title("Мое Приложение") + self.root.geometry("900x900") + self.root.configure(bg='#f0f0f0') + + # Позиционируем окно по левому краю экрана + self.position_window_left() + + # Увеличим шрифты для лучшей видимости на 7-дюймовом мониторе + self.big_font = ('Arial', 24) + self.medium_font = ('Arial', 20) + self.small_font = ('Arial', 16) + + self.create_widgets() + + 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="Minicom", + font=self.big_font, + bg='#FF9800', + fg='white', + width=15, + height=2, + command=self.open_minicom + ) + 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 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()}...") + import time + + 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()