import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import socket
import json
import datetime
# 全局变量用于模拟模式和连接状态
SIMULATION_MODE = True
PROGRAM_STARTED = False
epson_socket = None
config = {}
commands = []
# 模拟读取文件数据的函数,明确指定编码格式
def read_data_from_file(file_path):
data = []
try:
with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
for line in file:
line = line.strip()
if not line: # 跳过空行
continue
# 首先通过下划线分割出时间戳和坐标字符串
parts = line.split('_', 1)
if len(parts) != 2: # 确保有时间戳和坐标部分
update_log(log_text, f"Invalid data format in line: {line}")
continue
timestamp, coords_str = parts
coord_parts = coords_str.split('、')
if len(coord_parts) != 3: # 确保有三个坐标值
update_log(log_text, f"Invalid coordinate data in line: {line}")
continue
date_str, time_str = timestamp.split(' ')
formatted_time = f"{date_str} {time_str}"
try:
coordinates = [float(x) for x in coord_parts]
data.append((formatted_time, coordinates))
except ValueError as e:
update_log(log_text, f"Invalid coordinate data in line: {line}")
continue
except FileNotFoundError:
update_log(log_text, "Data file not found.")
except Exception as e:
update_log(log_text, f"An error occurred while reading the data file: {e}")
return data
# 解析配置文件并返回字典和指令列表
def parse_config_file(file_path):
config = {}
commands = []
section = None # 当前正在解析的部分
try:
with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
for line in file:
line = line.strip()
if line.startswith('[') and line.endswith(']'):
section = line[1:-1].strip().lower() # 获取部分名称并转为小写
continue # 跳过标题行
if line and section == '配置' and '=' in line:
key, value = line.split('=', 1)
config[key.strip()] = value.strip()
elif line and section == '程序':
commands.append(line.strip())
except FileNotFoundError:
update_log(log_text, "Config file not found.")
except Exception as e:
update_log(log_text, f"An error occurred while parsing the config file: {e}")
return config, commands
# 将数据显示在UI上
def display_data(data, text_widget):
text_widget.delete(1.0, tk.END)
for item in data:
time, coords = item
text_widget.insert(tk.END, f"Time: {time}, X: {coords[0]:.3f}, Y: {coords[1]:.3f}, R: {coords[2]:.3f}\n")
# 更新日志
def update_log(log_text, message):
current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_text.insert(tk.END, f'{current_time} - {message}\n')
log_text.see(tk.END)
# 发送JSON格式的指令给EPSON机器人
def send_command_to_epson_robot(socket_client, command):
message = json.dumps({"command": command})
try:
if SIMULATION_MODE:
update_log(log_text, f"[Simulation] Sent to EPSON Robot: {message}")
else:
socket_client.sendall(message.encode())
update_log(log_text, f"Sent to EPSON Robot: {message}")
except Exception as e:
update_log(log_text, f"Failed to send to EPSON Robot: {e}")
# 设置Socket连接到EPSON机器人
def setup_socket_connection(host, port):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
if SIMULATION_MODE:
update_log(log_text, "[Simulation] Connected to EPSON Robot")
return client_socket # 返回一个空套接字以模拟连接成功
else:
client_socket.connect((host, int(port)))
update_log(log_text, "Connected to EPSON Robot")
return client_socket
except Exception as e:
update_log(log_text, f"Connection failed: {e}")
return None
# 模拟连接成功的函数
def simulate_connection():
global epson_socket, SIMULATION_MODE, PROGRAM_STARTED
if epson_socket is None:
host = config.get('robot', '127.0.0.1') # 默认本地回环地址
port = config.get('port', '5000') # 默认端口
epson_socket = setup_socket_connection(host, port)
if epson_socket is not None:
update_log(log_text, "Simulated connection successful." if SIMULATION_MODE else "Connection successful.")
for command in commands:
send_command_to_epson_robot(epson_socket, command)
PROGRAM_STARTED = False # 确保模拟后需要再次点击开始
else:
update_log(log_text, "Failed to simulate connection.")
# 开始程序的函数
def start_program():
global SIMULATION_MODE, PROGRAM_STARTED
if not PROGRAM_STARTED:
SIMULATION_MODE = False
PROGRAM_STARTED = True
update_log(log_text, "Program started. Attempting real connection...")
simulate_connection() # 实际上调用simulate_connection来进行真实连接尝试
# GUI初始化
root = tk.Tk()
root.title("EPSON Robot Control Panel")
# 左侧数据显示框
data_text = ScrolledText(root, wrap=tk.WORD, width=40, height=15)
data_text.grid(row=0, column=0, padx=10, pady=10)
# 右侧日志显示框
log_text = ScrolledText(root, wrap=tk.WORD, width=40, height=15)
log_text.grid(row=0, column=1, padx=10, pady=10)
# 添加按钮用于模拟连接
connect_button = tk.Button(root, text="Simulate Connect", command=simulate_connection)
connect_button.grid(row=1, column=0, columnspan=2, pady=10)
# 添加按钮用于开始程序
start_button = tk.Button(root, text="Start Program", command=start_program)
start_button.grid(row=2, column=0, columnspan=2, pady=10)
# 主程序逻辑
if __name__ == "__main__":
# 文件路径
data_file_path = r'd:\data.txt'
config_file_path = r'd:\Robot_Config.txt'
# Socket连接设置 (从配置文件中获取)
config, commands = parse_config_file(config_file_path)
# 读取并显示数据
data = read_data_from_file(data_file_path)
display_data(data, data_text)
root.mainloop()