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


import time
import os
import tkinter as tk
from tkinter import filedialog, messagebox
from datetime import datetime
import xml.etree.ElementTree as ET
import hashlib

class UnicutMonitor:
    def __init__(self):
        self.xml_path = None
        self.last_change_time = None
        self.last_content_hash = None
        self.is_monitoring = False
        
    def set_file(self, path):
        """Установка файла для мониторинга"""
        if os.path.exists(path):
            self.xml_path = path
            self.last_change_time = self.get_max_change_time()
            self.last_content_hash = self.get_file_hash()
            self.is_monitoring = True
            return True
        return False
    
    def get_file_hash(self):
        """Получение хеша содержимого файла"""
        try:
            with open(self.xml_path, 'rb') as f:
                content = f.read()
                return hashlib.md5(content).hexdigest()
        except:
            return None
    
    def get_max_change_time(self):
        """Получение максимального времени изменения из файла"""
        try:
            tree = ET.parse(self.xml_path)
            root = tree.getroot()
            
            max_time = 0
            
            # Проверяем ChangeTime у материалов
            for material in root.findall('.//Material'):
                change_time = material.get('ChangeTime')
                if change_time:
                    max_time = max(max_time, int(change_time))
            
            # Проверяем Time у всех ParamValue
            for param_value in root.findall('.//ParamValue'):
                time_attr = param_value.get('Time')
                if time_attr and time_attr != '0':
                    max_time = max(max_time, int(time_attr))
            
            return max_time
        except:
            return None
    
    def check_changes(self):
        """Проверка изменений в файле"""
        if not self.is_monitoring or not self.xml_path:
            return None
        
        try:
            if not os.path.exists(self.xml_path):
                return None
            
            current_hash = self.get_file_hash()
            current_change_time = self.get_max_change_time()
            
            # Проверяем изменения по хешу и времени
            if (current_hash != self.last_content_hash or 
                current_change_time != self.last_change_time):
                
                print(f"[{datetime.now().strftime('%H:%M:%S')}] Обнаружены изменения:")
                print(f"  ChangeTime: {self.last_change_time} -> {current_change_time}")
                
                # Обновляем сохраненные значения
                self.last_content_hash = current_hash
                self.last_change_time = current_change_time
                
                return True
            
            return None
        except Exception as e:
            print(f"Ошибка проверки: {e}")
            return None

class LaserTimerApp:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("Секундомер резки - Unicut")
        self.window.geometry("600x450")
        self.window.attributes('-topmost', True)
        self.window.configure(bg='#1e1e1e')
        
        self.monitor = UnicutMonitor()
        self.total_time = 0
        self.is_cutting = False
        self.start_time = None
        self.operation_count = 0
        self.last_activity_time = time.time()
        self.inactivity_threshold = 90  # 90 секунд без изменений
        
        self.setup_ui()
        self.update()
    
    def setup_ui(self):
        # Заголовок
        title = tk.Label(self.window, text="СЕКУНДОМЕР ЛАЗЕРНОЙ РЕЗКИ",
                        font=("Arial", 16, "bold"),
                        bg='#1e1e1e', fg='white')
        title.pack(pady=10)
        
        # Информация о файле
        self.file_label = tk.Label(self.window, 
                                   text="Файл materials.xml не выбран",
                                   font=("Arial", 10),
                                   bg='#1e1e1e', fg='orange')
        self.file_label.pack()
        
        # Таймер
        self.time_label = tk.Label(self.window, text="00:00:00",
                                   font=("Arial", 60, "bold"),
                                   bg='#1e1e1e', fg='#00ff00')
        self.time_label.pack(pady=20)
        
        # Статус
        self.status_label = tk.Label(self.window, text="ОЖИДАНИЕ",
                                     font=("Arial", 14, "bold"),
                                     bg='#1e1e1e', fg='gray')
        self.status_label.pack()
        
        # Счетчик операций
        self.count_label = tk.Label(self.window, text="Операций: 0",
                                    font=("Arial", 11),
                                    bg='#1e1e1e', fg='white')
        self.count_label.pack(pady=5)
        
        # Кнопки
        button_frame = tk.Frame(self.window, bg='#1e1e1e')
        button_frame.pack(pady=15)
        
        select_btn = tk.Button(button_frame, text="ВЫБРАТЬ ФАЙЛ",
                              command=self.select_file,
                              font=("Arial", 11, "bold"),
                              width=15, height=2,
                              bg='#007acc', fg='white')
        select_btn.pack(side=tk.LEFT, padx=5)
        
        reset_btn = tk.Button(button_frame, text="СБРОС",
                             command=self.reset_timer,
                             font=("Arial", 11, "bold"),
                             width=10, height=2,
                             bg='#4a4a4a', fg='white')
        reset_btn.pack(side=tk.LEFT, padx=5)
        
        report_btn = tk.Button(button_frame, text="ОТЧЕТ",
                              command=self.save_report,
                              font=("Arial", 11, "bold"),
                              width=10, height=2,
                              bg='#4a4a4a', fg='white')
        report_btn.pack(side=tk.LEFT, padx=5)
    
    def select_file(self):
        """Выбор файла materials.xml"""
        filename = filedialog.askopenfilename(
            title="Выберите файл materials.xml",
            filetypes=[("XML files", "*.xml"), ("All files", "*.*")],
            initialdir=r"C:\Program Files\Unicut"
        )
        
        if filename:
            if self.monitor.set_file(filename):
                self.file_label.config(
                    text=f"Файл: {os.path.basename(filename)}",
                    fg='green'
                )
                messagebox.showinfo("Успех", 
                    f"Файл выбран:\n{filename}\n\nПрограмма отслеживает изменения.")
            else:
                messagebox.showerror("Ошибка", "Не удалось открыть файл")
    
    def update(self):
        try:
            if self.monitor.is_monitoring:
                change_detected = self.monitor.check_changes()
                
                if change_detected:
                    self.last_activity_time = time.time()
                    
                    if not self.is_cutting:
                        self.is_cutting = True
                        self.start_time = time.time()
                        self.operation_count += 1
                        self.status_label.config(text="РЕЗКА", fg='#00ff00')
                        self.count_label.config(text=f"Операций: {self.operation_count}")
                        print(f"[{datetime.now().strftime('%H:%M:%S')}] >>> РЕЗКА НАЧАЛАСЬ <<<")
                
                elif self.is_cutting and (time.time() - self.last_activity_time) > self.inactivity_threshold:
                    cut_duration = time.time() - self.start_time
                    self.total_time += cut_duration
                    self.is_cutting = False
                    self.status_label.config(text="ОЖИДАНИЕ", fg='gray')
                    print(f"[{datetime.now().strftime('%H:%M:%S')}] >>> Резка завершена: {cut_duration:.2f} сек <<<")
            
            # Обновляем таймер
            if self.is_cutting:
                current = self.total_time + (time.time() - self.start_time)
            else:
                current = self.total_time
            
            hours = int(current // 3600)
            minutes = int((current % 3600) // 60)
            seconds = int(current % 60)
            self.time_label.config(text=f"{hours:02d}:{minutes:02d}:{seconds:02d}")
            
        except Exception as e:
            print(f"Ошибка обновления: {e}")
        
        self.window.after(200, self.update)
    
    def reset_timer(self):
        self.total_time = 0
        self.is_cutting = False
        self.operation_count = 0
        self.last_activity_time = time.time()
        self.time_label.config(text="00:00:00")
        self.status_label.config(text="ОЖИДАНИЕ", fg='gray')
        self.count_label.config(text="Операций: 0")
        print("Таймер сброшен")
    
    def save_report(self):
        if self.total_time == 0 and not self.is_cutting:
            messagebox.showinfo("Информация", "Нет данных для отчета")
            return
        
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        filename = f"отчет_резки_{timestamp}.txt"
        
        with open(filename, 'w', encoding='utf-8') as f:
            f.write("="*50 + "\n")
            f.write("ОТЧЕТ О РАБОТЕ ЛАЗЕРНОГО СТАНКА\n")
            f.write("="*50 + "\n\n")
            f.write(f"Дата: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"Общее время резки: {self.time_label.cget('text')}\n")
            f.write(f"Количество операций: {self.operation_count}\n")
            f.write(f"Время в секундах: {self.total_time:.2f}\n\n")
            
            if self.monitor.xml_path:
                f.write(f"Файл мониторинга: {self.monitor.xml_path}\n")
            
            f.write("="*50 + "\n")
        
        messagebox.showinfo("Отчет сохранен", f"Отчет сохранен в файл:\n{filename}")
    
    def run(self):
        self.window.mainloop()

if __name__ == "__main__":
    print("="*60)
    print("СЕКУНДОМЕР ДЛЯ UNICUT")
    print("="*60)
    print("Отслеживание ChangeTime в materials.xml")
    print("="*60)
    
    try:
        app = LaserTimerApp()
        app.run()
    except Exception as e:
        print(f"Ошибка: {e}")
        import traceback
        traceback.print_exc()
        input("Нажмите Enter для выхода...")