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