From 3a746eddb7f68c643ee28f91ac2f153ea70ca77e Mon Sep 17 00:00:00 2001 From: xiongyi <827523911@qq.com> Date: Mon, 17 Nov 2025 21:56:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E7=A8=8B=E5=BA=8F=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E5=9C=A8=E6=90=85=E6=8B=8C=E6=A5=BC=E7=AB=AF=E8=BF=90?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/settings.py | 6 ++- database/access_db.py | 90 ++++++++++++++++++++----------- database/sql_server_connection.py | 2 +- main.py | 17 ++++-- services/monitoring_service.py | 6 +-- services/task_service.py | 39 ++++++++++++-- tcp/client.py | 70 ++++++++++++++++++++++++ 7 files changed, 184 insertions(+), 46 deletions(-) create mode 100644 tcp/client.py diff --git a/config/settings.py b/config/settings.py index 9d8c5db..7585765 100644 --- a/config/settings.py +++ b/config/settings.py @@ -26,7 +26,11 @@ SQL_SERVER_CONFIG = { TCP_HOST = '127.0.0.1' TCP_PORT = 8888 +# 新增TCP客户端配置 +TCP_CLIENT_HOST = '192.168.1.100' +TCP_CLIENT_PORT = 8889 + # 其他配置 MAX_AGE_HOURS = 24 CHECK_INTERVAL = 10 -MONITOR_INTERVAL = 2 +MONITOR_INTERVAL = 2 \ No newline at end of file diff --git a/database/access_db.py b/database/access_db.py index c2cd908..1e907fe 100644 --- a/database/access_db.py +++ b/database/access_db.py @@ -1,5 +1,6 @@ """Access数据库操作模块""" import pyodbc +import os class AccessDB: @@ -10,49 +11,74 @@ class AccessDB: def connect(self): """连接Access数据库""" - conn_str = ( - r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' - f'DBQ={self.db_path};' - f'PWD={self.password};' - ) - self.connection = pyodbc.connect(conn_str) - return self.connection + try: + # 检查网络路径是否存在 + if self.db_path.startswith('\\\\') and not os.path.exists(self.db_path): + raise FileNotFoundError(f"无法访问网络路径: {self.db_path},请检查网络连接和共享设置") + + conn_str = ( + r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' + f'DBQ={self.db_path};' + f'PWD={self.password};' + ) + self.connection = pyodbc.connect(conn_str) + return self.connection + except pyodbc.Error as e: + print(f"连接Access数据库失败: {e}") + raise + except FileNotFoundError as e: + print(f"数据库文件不可访问: {e}") + raise def get_max_mark(self): """获取Access数据库中最大的Mark值""" - if not self.connection: - self.connect() + try: + if not self.connection: + self.connect() - cursor = self.connection.cursor() - cursor.execute("SELECT MAX(Mark) FROM Produce") - max_mark = cursor.fetchone()[0] + cursor = self.connection.cursor() + cursor.execute("SELECT MAX(Mark) FROM Produce") + max_mark = cursor.fetchone()[0] - if max_mark is None: - max_mark = 0 + if max_mark is None: + max_mark = 0 - return max_mark + return max_mark + except pyodbc.Error as e: + print(f"查询最大Mark值时出错: {e}") + return 0 + except Exception as e: + print(f"获取最大Mark值时发生未知错误: {e}") + return 0 def query_task_status(self, mis_ids): """查询任务状态""" - if not self.connection: - self.connect() + try: + if not self.connection: + self.connect() - if not mis_ids: + if not mis_ids: + return {} + + cursor = self.connection.cursor() + placeholders = ','.join('?' * len(mis_ids)) + query = f"SELECT MISID, Flag FROM Produce WHERE MISID IN ({placeholders})" + cursor.execute(query, mis_ids) + results = cursor.fetchall() + + current_tasks = {} + for row in results: + mark = row[0] + flag = row[1] if row[1] is not None else "" + current_tasks[mark] = flag + + return current_tasks + except pyodbc.Error as e: + print(f"查询任务状态时出错: {e}") + return {} + except Exception as e: + print(f"查询任务状态时发生未知错误: {e}") return {} - - cursor = self.connection.cursor() - placeholders = ','.join('?' * len(mis_ids)) - query = f"SELECT MISID, Flag FROM Produce WHERE MISID IN ({placeholders})" - cursor.execute(query, mis_ids) - results = cursor.fetchall() - - current_tasks = {} - for row in results: - mark = row[0] - flag = row[1] if row[1] is not None else "" - current_tasks[mark] = flag - - return current_tasks def close(self): """关闭数据库连接""" diff --git a/database/sql_server_connection.py b/database/sql_server_connection.py index 55c9565..f392dc2 100644 --- a/database/sql_server_connection.py +++ b/database/sql_server_connection.py @@ -32,7 +32,7 @@ class SQLServerConnection: SELECT Code, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17 - FROM MixTable + FROM Recipe_back WHERE Code IS NOT NULL ORDER BY Code """ diff --git a/main.py b/main.py index 476ab8f..6146cc4 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,6 @@ """主程序入口""" import time import threading -from datetime import datetime from API.client import APIClient from API.mix_weight_api import MixWeightAPI from services.task_service import TaskService @@ -9,16 +8,17 @@ from services.monitoring_service import MonitoringService from database.access_db import AccessDB from database.sql_server import SQLServerDB from tcp.server import TCPServer +from tcp.client import TCPClient from config.settings import ( ACCESS_DB_PATH, ACCESS_DB_PASSWORD, - TCP_HOST, TCP_PORT, CHECK_INTERVAL, MAX_AGE_HOURS + TCP_HOST, TCP_PORT, TCP_CLIENT_HOST, TCP_CLIENT_PORT, + CHECK_INTERVAL, MAX_AGE_HOURS ) from utils.helpers import cleanup_old_timestamps # 假设同事提供的函数 def save_to_custom_table(misid, flag, task_id, produce_mix_id, project_name, beton_grade, adjusted_volume, artifact_id): """保存到自定义数据表的函数""" - # 这里应该是同事提供的实际实现 print(f"保存到自定义数据表: MISID={misid}, Flag={flag}, TaskID={task_id}, 调整后方量={adjusted_volume}") def start_api_service(): @@ -27,7 +27,7 @@ def start_api_service(): api.run(host='127.0.0.1', port=5001, debug=False, threaded=True) def main(): - global tcp_server + global tcp_server, data_client api_thread = threading.Thread(target=start_api_service) api_thread.daemon = True api_thread.start() @@ -38,6 +38,10 @@ def main(): tcp_server_thread.daemon = True tcp_server_thread.start() + # 初始化发送数据的TCP客户端 + data_client = TCPClient(host=TCP_CLIENT_HOST, port=TCP_CLIENT_PORT) + data_client.start() + # 等待服务端启动 time.sleep(1) @@ -129,7 +133,10 @@ def main(): # 停止TCP服务端 if 'tcp_server' in locals(): tcp_server.stop() + # 停止TCP客户端 + if 'data_client' in locals(): + data_client.stop() if __name__ == "__main__": - main() + main() \ No newline at end of file diff --git a/services/monitoring_service.py b/services/monitoring_service.py index d1dcdfd..9da7a2c 100644 --- a/services/monitoring_service.py +++ b/services/monitoring_service.py @@ -2,11 +2,9 @@ """监控服务""" import time import threading -from datetime import datetime from database.access_db import AccessDB from database.sql_server import SQLServerDB from config.settings import ACCESS_DB_PATH, ACCESS_DB_PASSWORD, MONITOR_INTERVAL -from tcp.server import TCPServer from services.task_service import TaskService class MonitoringService: @@ -103,7 +101,7 @@ class MonitoringService: self._handle_status_n(erp_id,artifact_id) elif current_flag.endswith('p'): self._handle_status_p(erp_id,artifact_id) - elif current_flag.endswith('x'): + elif current_flag.endswith('y'): self._handle_status_x(erp_id,artifact_id) def _handle_status_d(self,erp_id, artifact_id): @@ -191,7 +189,7 @@ class MonitoringService: print(f"发送状态数据给TCP客户端时出错: {e}") def _handle_status_x(self, erp_id,artifact_id): - """处理状态'x' - 数据已接收""" + """处理状态'y' - 数据已接收""" print(f"派发任务 ErpID {artifact_id}: 已插入") try: print(5) diff --git a/services/task_service.py b/services/task_service.py index 0baa681..e6ac01a 100644 --- a/services/task_service.py +++ b/services/task_service.py @@ -5,6 +5,7 @@ from database.access_db import AccessDB from database.sql_server import SQLServerDB from config.settings import ACCESS_DB_PATH, ACCESS_DB_PASSWORD from utils.helpers import get_f_block_positions +from tcp.client import TCPClient import threading import time @@ -16,6 +17,9 @@ class TaskService: self.task_before = {"block_number":None, "beton_volume":None, "artifact_id":None} self.artifact_timestamps = {} self.tcp_server = tcp_server + from config.settings import TCP_CLIENT_HOST, TCP_CLIENT_PORT + self.data_client = TCPClient(host=TCP_CLIENT_HOST, port=TCP_CLIENT_PORT) + self.data_client.start() def process_not_pour_info(self): """处理未浇筑信息""" @@ -394,8 +398,37 @@ class TaskService: return erp_id - def save_to_custom_table(self,misid, flag, task_id, produce_mix_id, project_name, beton_grade, adjusted_volume, artifact_id): - print(f"保存到自定义数据表: MISID={misid}, Flag={flag}, TaskID={task_id}, 调整后方量={adjusted_volume}") + def save_to_custom_table(self, misid, flag, task_id, produce_mix_id, project_name, beton_grade, adjusted_volume, artifact_id): + try: + task_data = { + "erp_id": misid, + "task_id": task_id, + "artifact_id": artifact_id, + "produce_mix_id": produce_mix_id, + "project_name": project_name, + "beton_grade": beton_grade, + "adjusted_volume": adjusted_volume, + "flag": flag, + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") + } + self.data_client.send_data(task_data) + print(f"任务 {artifact_id} 的数据已发送到另一台电脑") + except Exception as e: + print(f"发送数据到另一台电脑时出错: {e}") + print(f"原计划保存到自定义数据表: MISID={misid}, Flag={flag}, TaskID={task_id}, 调整后方量={adjusted_volume}") def update_custom_table_status(self, erp_id, status): - print(f"更新自定义数据表状态: ERP ID={erp_id}, 状态={status}") + # 通过专用TCP客户端发送状态更新到另一台电脑 + try: + status_data = { + "cmd": "update_status", + "erp_id": erp_id, + "status": status, + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") + } + self.data_client.send_data(status_data) + print(f"任务状态更新已发送到另一台电脑: ERP ID={erp_id}, 状态={status}") + except Exception as e: + print(f"发送状态更新到另一台电脑时出错: {e}") + print(f"原计划更新自定义数据表状态: ERP ID={erp_id}, 状态={status}") + diff --git a/tcp/client.py b/tcp/client.py new file mode 100644 index 0000000..e4bc758 --- /dev/null +++ b/tcp/client.py @@ -0,0 +1,70 @@ +import socket +import json +import threading +import time + + +class TCPClient: + def __init__(self, host='127.0.0.1', port=8889): + self.host = host + self.port = port + self.client_socket = None + self.is_connected = False + self.reconnect_interval = 5 # 重连间隔(秒) + self.is_running = False + + def connect(self): + """连接到TCP服务端""" + try: + self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.client_socket.connect((self.host, self.port)) + self.is_connected = True + print(f"已连接到 {self.host}:{self.port}") + return True + except Exception as e: + print(f"连接到服务端失败: {e}") + self.is_connected = False + return False + + def start(self): + """启动客户端并维持连接""" + self.is_running = True + reconnect_thread = threading.Thread(target=self._reconnect_worker, daemon=True) + reconnect_thread.start() + + def _reconnect_worker(self): + """重连工作线程""" + while self.is_running: + if not self.is_connected: + print(f"尝试重新连接到 {self.host}:{self.port}...") + self.connect() + time.sleep(self.reconnect_interval) + + def send_data(self, data): + """发送数据到服务端""" + if not self.is_connected or not self.client_socket: + print("客户端未连接到服务端") + return False + + try: + json_data = json.dumps(data, ensure_ascii=False) + # 添加换行符作为结束标记 + self.client_socket.sendall((json_data + "\n").encode('utf-8')) + print(f"已发送数据: {json_data}") + return True + except Exception as e: + print(f"发送数据时出错: {e}") + self.is_connected = False + return False + + def stop(self): + """停止客户端""" + self.is_running = False + self.is_connected = False + if self.client_socket: + try: + self.client_socket.close() + except Exception as e: + print(f"关闭客户端套接字时出错: {e}") + print("TCP客户端已停止") +