Files
StandGUI/myscript.py

623 lines
28 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
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()