From 60c348cba6f4745ff5891213b25da0412c69189d Mon Sep 17 00:00:00 2001 From: gcw_MV9p2JJN Date: Sun, 1 Feb 2026 19:55:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=AB=E7=A0=81=E4=B9=8B=E5=90=8E=E7=BB=99PL?= =?UTF-8?q?C=E4=B8=8B=E5=8F=91=E4=BA=A7=E5=93=81=E5=9E=8B=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Infrastructure/Helper/SiemensS7Helper.cs | 61 +++++++++++++------ .../Mes/WorkOrderInfo/WorkOrderController.cs | 10 ++- .../WorkOrderInfo/IWorkOrderService.cs | 2 + .../Mes/WorkOrderInfo/WorkOrderService.cs | 34 ++++++++++- .../PLCbackTask/MES_PLC_InterationTask.cs | 7 ++- 5 files changed, 92 insertions(+), 22 deletions(-) diff --git a/Infrastructure/Helper/SiemensS7Helper.cs b/Infrastructure/Helper/SiemensS7Helper.cs index 1a11e68..4f47874 100644 --- a/Infrastructure/Helper/SiemensS7Helper.cs +++ b/Infrastructure/Helper/SiemensS7Helper.cs @@ -18,6 +18,7 @@ namespace RIZO.Infrastructure.Helper { private SiemensS7Net _plc; private bool _isConnected = false; + private string IP; /// /// 连接状态 @@ -33,47 +34,73 @@ namespace RIZO.Infrastructure.Helper _plc = new SiemensS7Net(SiemensPLCS.S1500) { IpAddress = ip, + Port = 102 }; + IP = ip; } /// - /// 连接PLC + /// 连接PLC(修正版) /// public async Task ConnectAsync(CancellationToken cancellationToken = default) { int maxRetries = 3; int retryDelayMs = 2000; - int attempt = 0; - while (attempt < maxRetries) + // 如果已经连接,直接返回成功 + if (_isConnected && _plc != null) + return true; + + for (int attempt = 1; attempt <= maxRetries; attempt++) { - attempt++; - - var result = await Task.Run(() => _plc.ConnectServer()); - _isConnected = result.IsSuccess; - if (!_isConnected) + try { + Console.WriteLine($"连接尝试 {attempt}/{maxRetries} - IP: {IP}"); - Console.WriteLine($"连接尝试 {attempt}/{maxRetries} 失败"); + var result = await Task.Run(() => _plc.ConnectServer(), cancellationToken); + _isConnected = result.IsSuccess; + + if (_isConnected) + { + Console.WriteLine($"PLC连接成功 - IP: {IP}"); + return true; + } + else + { + Console.WriteLine($"连接尝试 {attempt}/{maxRetries} 失败: {result.Message},IP: {IP}"); + + // 如果不是最后一次尝试,则等待后重试 + if (attempt < maxRetries) + { + Console.WriteLine($"{retryDelayMs / 1000}秒后重试..."); + await Task.Delay(retryDelayMs, cancellationToken); + } + } + } + catch (OperationCanceledException) + { + Console.WriteLine("IP: {IP} 连接操作已取消"); + break; + } + catch (Exception ex) + { + Console.WriteLine($"连接尝试 {attempt}/{maxRetries} 发生异常: {ex.Message},IP: {IP}"); if (attempt < maxRetries) { Console.WriteLine($"{retryDelayMs / 1000}秒后重试..."); await Task.Delay(retryDelayMs, cancellationToken); } - else - { - Console.WriteLine("无法建立PLC连接,请检查网络和设备状态"); - _plc?.ConnectClose(); - _plc = null; - return _isConnected; - } } } + + // 所有重试都失败了 + Console.WriteLine($"无法建立 {IP} PLC连接,请检查网络和设备状态"); + _plc?.ConnectClose(); + _isConnected = false; return false; } - /// /// 断开连接 /// diff --git a/RIZO.Admin.WebApi/Controllers/Mes/WorkOrderInfo/WorkOrderController.cs b/RIZO.Admin.WebApi/Controllers/Mes/WorkOrderInfo/WorkOrderController.cs index f70113c..36e79cc 100644 --- a/RIZO.Admin.WebApi/Controllers/Mes/WorkOrderInfo/WorkOrderController.cs +++ b/RIZO.Admin.WebApi/Controllers/Mes/WorkOrderInfo/WorkOrderController.cs @@ -196,5 +196,13 @@ namespace RIZO.Admin.WebApi.Controllers.Mes.WorkOrderInfo var response = _WorkOrderService.QueryWorkOrderToDay(parm); return response; } - } + + //TODO 扫码之后给PLC下发产品型号 + [HttpGet("scan_product_model")] + public IActionResult ScanProductModel( int scanCode) + { + var response = _WorkOrderService.ScanProductModel(scanCode).; + return SUCCESS(response); + + } } \ No newline at end of file diff --git a/RIZO.Service/Mes/IMesService/WorkOrderInfo/IWorkOrderService.cs b/RIZO.Service/Mes/IMesService/WorkOrderInfo/IWorkOrderService.cs index 797a353..d96cd78 100644 --- a/RIZO.Service/Mes/IMesService/WorkOrderInfo/IWorkOrderService.cs +++ b/RIZO.Service/Mes/IMesService/WorkOrderInfo/IWorkOrderService.cs @@ -31,5 +31,7 @@ namespace RIZO.Service.Mes.IMesService.WorkOrderInfo List QueryWorkOrderMonth(); ApiResult QueryWorkOrderToDay(WorkOrderTodayDto parm); + + Task ScanProductModel(int scanCode); } } diff --git a/RIZO.Service/Mes/WorkOrderInfo/WorkOrderService.cs b/RIZO.Service/Mes/WorkOrderInfo/WorkOrderService.cs index f3352db..798693c 100644 --- a/RIZO.Service/Mes/WorkOrderInfo/WorkOrderService.cs +++ b/RIZO.Service/Mes/WorkOrderInfo/WorkOrderService.cs @@ -2,7 +2,11 @@ using Aliyun.OSS; using Infrastructure.Attribute; using Infrastructure.Extensions; using Infrastructure.Model; +using MDM.Services.Material; +using MDM.Services.Process; using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Options; +using RIZO.Infrastructure.Helper; using RIZO.Model.Mes.Dto.WorkOrderInfo; using RIZO.Model.Mes.MasterData; using RIZO.Model.Mes.WorkOrderInfo; @@ -10,8 +14,6 @@ using RIZO.Repository; using RIZO.Service.Mes.IMesService.MasterData; using RIZO.Service.Mes.IMesService.WorkOrderInfo; using RIZO.Service.Mes.MasterData; -using MDM.Services.Process; -using MDM.Services.Material; using SqlSugar; using SqlSugar.Extensions; using static System.Runtime.InteropServices.JavaScript.JSType; @@ -27,6 +29,12 @@ namespace RIZO.Service.Mes.WorkOrderInfo private WorkOrderItemService workOrderItemService = new WorkOrderItemService(); private MaterialListService materialListService = new MaterialListService(); private ProcessRoutingService processRoutingService = new ProcessRoutingService(); + + private readonly PlcAddress _plcAddress; + public WorkOrderService(IOptions options) + { + _plcAddress = options.Value.plcAddress; + } /// /// 查询工单主表列表 /// @@ -440,5 +448,27 @@ namespace RIZO.Service.Mes.WorkOrderInfo return ApiResult.Error(ex.Message); } } + private SiemensS7Helper s7Helper; + public async Task ScanProductModel(int ScanProductModelId) + { + using(s7Helper = new SiemensS7Helper(_plcAddress.IP)) + { + if (!s7Helper.IsConnected) + { + var isConnected = await s7Helper.ConnectAsync(); + if (!isConnected) + { + return; + } + + await s7Helper.WriteIntAsync(_plcAddress.Write.ScanProductModelId, (short)ScanProductModelId); + await s7Helper.WriteBoolAsync(_plcAddress.Write.ScanOk, true); + await s7Helper.WriteBoolAsync(_plcAddress.Write.ScanNg, false); + + + + } + } + } } } \ No newline at end of file diff --git a/RIZO.Service/PLCbackTask/MES_PLC_InterationTask.cs b/RIZO.Service/PLCbackTask/MES_PLC_InterationTask.cs index 65b47dd..1a15cf5 100644 --- a/RIZO.Service/PLCbackTask/MES_PLC_InterationTask.cs +++ b/RIZO.Service/PLCbackTask/MES_PLC_InterationTask.cs @@ -64,10 +64,13 @@ namespace RIZO.Service.PLCbackTask // 使用内部取消源停止循环,而不是直接return _internalCts.Cancel(); break; // 跳出循环,但会继续执行finally块和Dispose + }else if(ReadHeartBeat != null && ReadHeartBeat.Value) + { + await s7Helper.WriteBoolAsync(_plcAddress.Write.WriteHeartBeat, true); } - //TODO :1. 轮询出站请求 - bool? OutStationAsk = await s7Helper.ReadBoolAsync(_plcAddress.Read.OutStationAsk); + //TODO :1. 轮询出站请求 + bool? OutStationAsk = await s7Helper.ReadBoolAsync(_plcAddress.Read.OutStationAsk); if (OutStationAsk != null && OutStationAsk.Value) { //TODO : 2.读取业务数据