Загрузка данных
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 для выхода...")