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


import time
import os
import tkinter as tk
from datetime import datetime
import xml.etree.ElementTree as ET

class UnicutXMLMonitor:
    def __init__(self):
        self.xml_path = None
        self.last_modified_time = None
        self.last_content = None
        self.find_xml_file()
    
    def find_xml_file(self):
        """Поиск файла materials.xml"""
        print("=" * 50)
        print("Поиск файла materials.xml...")
        print("=" * 50)
        
        # Возможные пути к файлу
        possible_paths = [
            r"C:\Program Files\Unicut\materials.xml",
            r"C:\Program Files (x86)\Unicut\materials.xml",
            r"C:\Unicut\materials.xml",
            r"D:\Unicut\materials.xml",
            r"C:\Program Files\Unimash\materials.xml",
            r"C:\Program Files (x86)\Unimash\materials.xml",
            r"C:\Unimash\materials.xml",
            r"D:\Unimash\materials.xml",
            r"C:\ProgramData\Unicut\materials.xml",
            r"C:\ProgramData\Unimash\materials.xml",
            # Поиск в документах
            os.path.expanduser(r"~\Documents\Unicut\materials.xml"),
            os.path.expanduser(r"~\Documents\Unimash\materials.xml"),
        ]
        
        for path in possible_paths:
            if os.path.exists(path):
                print(f"НАЙДЕН ФАЙЛ: {path}")
                self.xml_path = path
                self.last_modified_time = os.path.getmtime(path)
                self.last_content = self.read_xml_content()
                return
        
        # Если не нашли в стандартных местах, ищем по всему диску C:
        print("Стандартные пути не найдены.")
        print("Ищу файл materials.xml на диске C:...")
        
        try:
            for root, dirs, files in os.walk(r"C:\"):
                if 'materials.xml' in files:
                    full_path = os.path.join(root, 'materials.xml')
                    print(f"НАЙДЕН ФАЙЛ: {full_path}")
                    self.xml_path = full_path
                    self.last_modified_time = os.path.getmtime(full_path)
                    self.last_content = self.read_xml_content()
                    return
                # Ограничим поиск, чтобы не было долго
                if root.count(os.sep) > 3:
                    dirs.clear()
        except Exception as e:
            print(f"Ошибка при поиске: {e}")
        
        print("Файл materials.xml не найден автоматически")
    
    def read_xml_content(self):
        """Чтение содержимого XML файла"""
        try:
            with open(self.xml_path, 'r', encoding='utf-8', errors='ignore') as f:
                return f.read()
        except:
            return None
    
    def check_status(self):
        """Проверка изменений в файле materials.xml"""
        try:
            if not self.xml_path or not os.path.exists(self.xml_path):
                return None
            
            # Проверяем время изменения файла
            current_modified_time = os.path.getmtime(self.xml_path)
            current_content = self.read_xml_content()
            
            # Если файл изменился
            if current_modified_time != self.last_modified_time or current_content != self.last_content:
                print(f"[{datetime.now().strftime('%H:%M:%S')}] Файл materials.xml изменен")
                
                # Анализируем содержимое
                status = self.analyze_xml_content(current_content)
                
                # Обновляем сохраненные данные
                self.last_modified_time = current_modified_time
                self.last_content = current_content
                
                return status
            
            return None
        except Exception as e:
            print(f"Ошибка при проверке файла: {e}")
            return None
    
    def analyze_xml_content(self, content):
        """Анализ содержимого XML для определения статуса резки"""
        if not content:
            return None
        
        try:
            # Пытаемся распарсить XML
            root = ET.fromstring(content)
            
            # Ищем признаки активной резки
            # Разные версии Unicut могут иметь разную структуру
            
            # Проверяем различные возможные теги и атрибуты
            cutting_indicators = [
                'cutting', 'Cutting', 'CUTTING',
                'laser_on', 'LaserOn', 'LASER_ON',
                'active', 'Active', 'ACTIVE',
                'processing', 'Processing', 'PROCESSING',
                'working', 'Working', 'WORKING',
                'in_progress', 'InProgress', 'IN_PROGRESS'
            ]
            
            # Ищем в тексте
            content_lower = content.lower()
            
            # Проверяем признаки резки
            for indicator in cutting_indicators:
                if indicator.lower() in content_lower:
                    # Проверяем контекст (включено или выключено)
                    if 'true' in content_lower or 'yes' in content_lower or 'on' in content_lower or 'active' in content_lower:
                        return True
            
            # Проверяем признаки остановки
            idle_indicators = [
                'idle', 'Idle', 'IDLE',
                'standby', 'Standby', 'STANDBY',
                'waiting', 'Waiting', 'WAITING',
                'stopped', 'Stopped', 'STOPPED',
                'paused', 'Paused', 'PAUSED'
            ]
            
            for indicator in idle_indicators:
                if indicator.lower() in content_lower:
                    return False
            
            return None
        except ET.ParseError:
            # Если не удалось распарсить XML, просто ищем текст
            content_lower = content.lower()
            
            if any(word in content_lower for word in ['cutting', 'laser_on', 'active', 'processing', 'working']):
                if 'true' in content_lower or 'on' in content_lower:
                    return True
            
            if any(word in content_lower for word in ['idle', 'standby', 'stopped', 'waiting']):
                return False
            
            return None

class MaterialsXMLTimer:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("Секундомер резки - Unicut")
        self.window.geometry("500x350")
        self.window.attributes('-topmost', True)
        self.window.configure(bg='#1e1e1e')
        
        self.monitor = UnicutXMLMonitor()
        self.total_time = 0
        self.is_cutting = False
        self.start_time = None
        self.operation_count = 0
        
        self.setup_ui()
        self.update()
    
    def setup_ui(self):
        # Заголовок
        title = tk.Label(self.window, text="СЕКУНДОМЕР ЛАЗЕРНОЙ РЕЗКИ",
                        font=("Arial", 14, "bold"),
                        bg='#1e1e1e', fg='white')
        title.pack(pady=10)
        
        # Статус подключения к файлу
        if self.monitor.xml_path:
            file_status = f"Файл: {os.path.basename(self.monitor.xml_path)}"
            file_color = "green"
        else:
            file_status = "Файл materials.xml не найден"
            file_color = "red"
        
        self.file_label = tk.Label(self.window, text=file_status,
                                   font=("Arial", 9),
                                   bg='#1e1e1e', fg=file_color)
        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", 10),
                                    bg='#1e1e1e', fg='white')
        self.count_label.pack(pady=5)
        
        # Кнопки
        button_frame = tk.Frame(self.window, bg='#1e1e1e')
        button_frame.pack(pady=10)
        
        reset_btn = tk.Button(button_frame, text="СБРОС",
                             command=self.reset,
                             font=("Arial", 12, "bold"),
                             width=10, height=2,
                             bg='#4a4a4a', fg='white')
        reset_btn.pack(side=tk.LEFT, padx=5)
        
        # Кнопка ручного выбора файла
        select_btn = tk.Button(button_frame, text="ВЫБРАТЬ ФАЙЛ",
                              command=self.select_file,
                              font=("Arial", 10),
                              width=12, height=2,
                              bg='#4a4a4a', fg='white')
        select_btn.pack(side=tk.LEFT, padx=5)
    
    def select_file(self):
        """Ручной выбор файла materials.xml"""
        from tkinter import filedialog, messagebox
        
        filename = filedialog.askopenfilename(
            title="Выберите файл materials.xml",
            filetypes=[("XML files", "*.xml"), ("All files", "*.*")]
        )
        
        if filename:
            self.monitor.xml_path = filename
            self.monitor.last_modified_time = os.path.getmtime(filename)
            self.monitor.last_content = self.monitor.read_xml_content()
            self.file_label.config(text=f"Файл: {os.path.basename(filename)}", fg="green")
            messagebox.showinfo("Успех", f"Выбран файл:\n{filename}")
    
    def update(self):
        try:
            status = self.monitor.check_status()
            
            if status == True and 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 status == False and self.is_cutting:
                # Резка закончилась
                cut_time = time.time() - self.start_time
                self.total_time += cut_time
                self.is_cutting = False
                self.status_label.config(text="ОЖИДАНИЕ", fg='gray')
                print(f"[{datetime.now().strftime('%H:%M:%S')}] >>> Резка завершена: {cut_time:.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}")
        
        # Проверяем каждые 0.5 секунды
        self.window.after(500, self.update)
    
    def reset(self):
        """Сброс таймера"""
        self.total_time = 0
        self.is_cutting = False
        self.operation_count = 0
        self.time_label.config(text="00:00:00")
        self.status_label.config(text="ОЖИДАНИЕ", fg='gray')
        self.count_label.config(text="Операций: 0")
        print("Таймер сброшен")
    
    def run(self):
        self.window.mainloop()

if __name__ == "__main__":
    print("=" * 60)
    print("ПРОГРАММА ОТСЛЕЖИВАНИЯ РЕЗКИ ЧЕРЕЗ materials.xml")
    print("=" * 60)
    
    try:
        app = MaterialsXMLTimer()
        app.run()
    except Exception as e:
        print(f"КРИТИЧЕСКАЯ ОШИБКА: {e}")
        import traceback
        traceback.print_exc()
        input("Нажмите Enter для выхода...")