Загрузка данных


import time
import serial
import threading
import tkinter as tk
from datetime import datetime
from serial.tools import list_ports

class LaserTimer:
    def __init__(self):
        self.running = False
        self.start_time = None
        self.total_time = 0
        self.last_change = None
        self.serial_port = None
        self.is_connected = False
        
        # Автоматический поиск порта
        self.find_port()
    
    def find_port(self):
        """Автоматический поиск COM-порта"""
        ports = list_ports.comports()
        print("Найденные порты:")
        for port in ports:
            print(f"  - {port.device}: {port.description}")
            # Попробуем подключиться к первому доступному
            if not self.serial_port:
                try:
                    self.serial_port = serial.Serial(port.device, 9600, timeout=1)
                    self.is_connected = True
                    print(f"Подключено к {port.device}")
                except:
                    print(f"Не удалось подключиться к {port.device}")
    
    def connect_to_port(self, port_name):
        """Подключение к указанному порту"""
        try:
            if self.serial_port:
                self.serial_port.close()
            self.serial_port = serial.Serial(port_name, 9600, timeout=1)
            self.is_connected = True
            return True
        except:
            self.is_connected = False
            return False
    
    def check_laser_status(self):
        """Проверка статуса лазера через serial порт"""
        try:
            if self.serial_port and self.serial_port.in_waiting > 0:
                data = self.serial_port.readline().decode('utf-8', errors='ignore')
                print(f"Получены данные: {data.strip()}")  # Для отладки
                
                # Ищем команды включения/выключения лазера
                # Разные станки могут использовать разные команды
                if 'M3' in data.upper() or 'M03' in data.upper() or 'LASER_ON' in data.upper() or 'ON' in data.upper():
                    return True
                elif 'M5' in data.upper() or 'M05' in data.upper() or 'LASER_OFF' in data.upper() or 'OFF' in data.upper():
                    return False
            return None
        except Exception as e:
            print(f"Ошибка чтения порта: {e}")
            return None

class TimerGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Секундомер лазерной резки - Unimash")
        self.root.geometry("500x300")
        self.root.attributes('-topmost', True)  # Поверх всех окон
        self.root.configure(bg='#2b2b2b')
        
        self.timer = LaserTimer()
        self.total_cut_time = 0
        self.is_cutting = False
        self.start_cut_time = None
        self.cut_count = 0
        
        # Настройка цветов
        self.bg_color = '#2b2b2b'
        self.fg_color = '#ffffff'
        self.accent_color = '#00ff00'
        
        self.setup_ui()
        self.monitor()
        
    def setup_ui(self):
        # Заголовок
        title_label = tk.Label(self.root, text="ВРЕМЯ РЕЗКИ", 
                               font=("Arial", 16, "bold"),
                               bg=self.bg_color, fg=self.fg_color)
        title_label.pack(pady=10)
        
        # Основной таймер
        self.label = tk.Label(self.root, text="00:00:00", 
                              font=("Arial", 60, "bold"),
                              bg=self.bg_color, fg=self.accent_color)
        self.label.pack(pady=10)
        
        # Статус
        status_frame = tk.Frame(self.root, bg=self.bg_color)
        status_frame.pack(pady=10)
        
        self.status_indicator = tk.Label(status_frame, text="●", 
                                        font=("Arial", 20),
                                        bg=self.bg_color, fg="gray")
        self.status_indicator.pack(side=tk.LEFT, padx=5)
        
        self.status_label = tk.Label(status_frame, text="Ожидание", 
                                     font=("Arial", 14),
                                     bg=self.bg_color, fg="gray")
        self.status_label.pack(side=tk.LEFT)
        
        # Информация
        self.info_label = tk.Label(self.root, 
                                   text=f"Операций: {self.cut_count} | Порт: {'Подключен' if self.timer.is_connected else 'Не подключен'}",
                                   font=("Arial", 10),
                                   bg=self.bg_color, fg=self.fg_color)
        self.info_label.pack(pady=5)
        
        # Кнопки
        button_frame = tk.Frame(self.root, bg=self.bg_color)
        button_frame.pack(pady=10)
        
        self.reset_button = tk.Button(button_frame, text="Сбросить", 
                                      command=self.reset_timer,
                                      width=12, font=("Arial", 11),
                                      bg='#4a4a4a', fg='white')
        self.reset_button.pack(side=tk.LEFT, padx=5)
        
        self.export_button = tk.Button(button_frame, text="Сохранить отчет", 
                                       command=self.export_data,
                                       width=15, font=("Arial", 11),
                                       bg='#4a4a4a', fg='white')
        self.export_button.pack(side=tk.LEFT, padx=5)
        
        # Подсказка
        hint_label = tk.Label(self.root, 
                             text="Программа автоматически отслеживает включение лазера",
                             font=("Arial", 8),
                             bg=self.bg_color, fg='#888888')
        hint_label.pack(side=tk.BOTTOM, pady=5)
        
    def monitor(self):
        """Постоянный мониторинг состояния лазера"""
        status = self.timer.check_laser_status()
        
        # Обработка изменения статуса
        if status == True and not self.is_cutting:
            # Лазер начал резать
            self.is_cutting = True
            self.start_cut_time = time.time()
            self.cut_count += 1
            self.status_indicator.config(fg="green")
            self.status_label.config(text="РЕЗКА", fg="green")
            self.info_label.config(text=f"Операций: {self.cut_count} | Порт: {'Подключен' if self.timer.is_connected else 'Не подключен'}")
            print(f"[{datetime.now().strftime('%H:%M:%S')}] Резка началась")
            
        elif status == False and self.is_cutting:
            # Лазер остановился
            if self.start_cut_time:
                cut_duration = time.time() - self.start_cut_time
                self.total_cut_time += cut_duration
                print(f"[{datetime.now().strftime('%H:%M:%S')}] Резка завершена: {cut_duration:.2f} сек")
            self.is_cutting = False
            self.status_indicator.config(fg="orange")
            self.status_label.config(text="Ожидание", fg="orange")
        
        # Обновление отображения времени
        if self.is_cutting and self.start_cut_time:
            current_time = self.total_cut_time + (time.time() - self.start_cut_time)
        else:
            current_time = self.total_cut_time
            
        hours = int(current_time // 3600)
        minutes = int((current_time % 3600) // 60)
        seconds = int(current_time % 60)
        self.label.config(text=f"{hours:02d}:{minutes:02d}:{seconds:02d}")
        
        # Повторяем каждые 100 мс
        self.root.after(100, self.monitor)
    
    def reset_timer(self):
        """Сброс таймера"""
        self.total_cut_time = 0
        self.start_cut_time = None
        self.is_cutting = False
        self.cut_count = 0
        self.label.config(text="00:00:00")
        self.status_indicator.config(fg="gray")
        self.status_label.config(text="Ожидание", fg="gray")
        self.info_label.config(text=f"Операций: {self.cut_count} | Порт: {'Подключен' if self.timer.is_connected else 'Не подключен'}")
        print("Таймер сброшен")
    
    def export_data(self):
        """Экспорт данных в файл"""
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        filename = f"laser_time_{timestamp}.txt"
        
        with open(filename, 'w', encoding='utf-8') as f:
            f.write("="*50 + "\n")
            f.write("ОТЧЕТ О РАБОТЕ ЛАЗЕРНОГО СТАНКА\n")
            f.write("="*50 + "\n")
            f.write(f"Дата: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"Общее время резки: {self.label.cget('text')}\n")
            f.write(f"Количество операций: {self.cut_count}\n")
            f.write(f"Время в секундах: {self.total_cut_time:.2f}\n")
            f.write("="*50 + "\n")
            
        print(f"Отчет сохранен в файл: {filename}")
        # Можно показать сообщение пользователю
        tk.messagebox.showinfo("Успех", f"Отчет сохранен в файл:\n{filename}")
    
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = TimerGUI()
    app.run()