Загрузка данных
import time
import serial
import serial.tools.list_ports
import tkinter as tk
from datetime import datetime
import os
import glob
class LaserTimerFO3015:
def __init__(self):
self.serial_port = None
self.port_name = None
self.connection_type = None
self.auto_connect()
def auto_connect(self):
"""Автоматический поиск подключения к станку FO3015"""
print("=" * 50)
print("Поиск подключения к станку FO3015...")
print("=" * 50)
# Сначала пробуем найти COM-порты
ports = list(serial.tools.list_ports.comports())
if len(ports) > 0:
print(f"Найдено портов: {len(ports)}")
for port in ports:
print(f"\nПробуем порт: {port.device}")
print(f"Описание: {port.description}")
# Пробуем разные скорости
for baudrate in [9600, 19200, 38400, 57600, 115200]:
try:
ser = serial.Serial(
port=port.device,
baudrate=baudrate,
timeout=0.5,
bytesize=8,
parity='N',
stopbits=1
)
print(f" Успех! Порт {port.device}, скорость {baudrate}")
self.serial_port = ser
self.port_name = port.device
self.connection_type = "serial"
return
except:
pass
else:
print("COM-порты не найдены")
print("Возможно, станок подключен через Ethernet")
# Если порты не найдены, пробуем найти файлы-маркеры Unicut
self.find_unicut_files()
def find_unicut_files(self):
"""Поиск файлов программы Unicut"""
possible_paths = [
r"C:\Program Files\Unicut",
r"C:\Program Files (x86)\Unicut",
r"C:\Unicut",
r"D:\Unicut",
r"C:\Program Files\Unimash",
r"C:\Program Files (x86)\Unimash",
r"C:\Unimash"
]
print("\nПоиск файлов Unicut...")
for path in possible_paths:
if os.path.exists(path):
print(f"Найдена папка: {path}")
# Ищем лог-файлы
log_files = glob.glob(os.path.join(path, "**", "*.log"), recursive=True)
if log_files:
print(f"Найдены лог-файлы: {log_files[:5]}")
self.log_file = log_files[0]
self.connection_type = "file"
return
print("Файлы Unicut не найдены")
def check_laser_status(self):
"""Проверка статуса лазера"""
if self.connection_type == "serial" and self.serial_port:
return self.check_serial_status()
elif self.connection_type == "file" and hasattr(self, 'log_file'):
return self.check_file_status()
return None
def check_serial_status(self):
"""Проверка через COM-порт"""
try:
if self.serial_port.in_waiting > 0:
data = self.serial_port.readline().decode('utf-8', errors='ignore')
if data.strip():
print(f"Данные от станка: {repr(data.strip())}")
data_upper = data.upper()
# Команды для оптоволоконных лазеров FO3015
laser_on_commands = [
'M3', 'M03', # Стандартные команды
'LASER_ON', # Лазер включен
'BEAM_ON', # Луч включен
'POWER_ON', # Питание включено
'EMISSION_ON', # Излучение включено
'CUTTING_START', # Начало резки
'START_CUT', # Начало резки
'G1', 'G01', # Линейное перемещение (часто с лазером)
'ENABLE', # Разрешение
]
laser_off_commands = [
'M5', 'M05', # Стандартные команды
'LASER_OFF', # Лазер выключен
'BEAM_OFF', # Луч выключен
'POWER_OFF', # Питание выключено
'EMISSION_OFF', # Излучение выключено
'CUTTING_END', # Конец резки
'STOP_CUT', # Конец резки
'G0', 'G00', # Быстрое перемещение (без лазера)
'DISABLE', # Запрет
]
for cmd in laser_on_commands:
if cmd in data_upper:
return True
for cmd in laser_off_commands:
if cmd in data_upper:
return False
return None
except Exception as e:
print(f"Ошибка чтения порта: {e}")
return None
def check_file_status(self):
"""Проверка через файлы Unicut"""
try:
if not os.path.exists(self.log_file):
return None
with open(self.log_file, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
content_upper = content.upper()
if 'LASER ON' in content_upper or 'CUTTING' in content_upper:
return True
elif 'LASER OFF' in content_upper or 'IDLE' in content_upper:
return False
return None
except:
return None
class TimerApp:
def __init__(self):
self.window = tk.Tk()
self.window.title("Секундомер FO3015")
self.window.geometry("500x300")
self.window.attributes('-topmost', True)
self.window.configure(bg='#1e1e1e')
self.timer = LaserTimerFO3015()
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="ЛАЗЕРНЫЙ СТАНОК FO3015",
font=("Arial", 14, "bold"),
bg='#1e1e1e', fg='white')
title.pack(pady=5)
# Информация о подключении
if self.timer.connection_type:
conn_text = f"Подключение: {self.timer.connection_type.upper()}"
conn_color = "green"
else:
conn_text = "Нет подключения"
conn_color = "red"
self.conn_label = tk.Label(self.window, text=conn_text,
font=("Arial", 10),
bg='#1e1e1e', fg=conn_color)
self.conn_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)
# Кнопка сброса
reset_btn = tk.Button(self.window, text="СБРОС",
command=self.reset,
font=("Arial", 12, "bold"),
width=10, height=2,
bg='#4a4a4a', fg='white')
reset_btn.pack(pady=10)
def update(self):
status = self.timer.check_laser_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}")
self.window.after(100, 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("=" * 50)
print("ПРОГРАММА ДЛЯ СТАНКА FO3015")
print("=" * 50)
app = TimerApp()
app.run()