diff --git a/RIZO.Admin.WebApi/Program.cs b/RIZO.Admin.WebApi/Program.cs index 910fe55..adca6da 100644 --- a/RIZO.Admin.WebApi/Program.cs +++ b/RIZO.Admin.WebApi/Program.cs @@ -112,7 +112,7 @@ builder.Services.AddLocalization(options => options.ResourcesPath = ""); //builder.Services.AddHostedService(); //builder.Services.AddHostedService(); - +builder.Services.AddHostedService(); // 在应用程序启动的最开始处调用 var app = builder.Build(); diff --git a/RIZO.Service/PLCBackground/PlcConntectHepler.cs b/RIZO.Service/PLCBackground/PlcConntectHepler.cs index 8da255a..a867616 100644 --- a/RIZO.Service/PLCBackground/PlcConntectHepler.cs +++ b/RIZO.Service/PLCBackground/PlcConntectHepler.cs @@ -129,6 +129,39 @@ namespace RIZO.Service.PLC } } + public async Task WriteAsync2(string address, object value, CancellationToken cancellationToken = default) + { + await _semaphore.WaitAsync(cancellationToken); + try + { + // 1. 确保PLC连接正常 + if (_plc == null || !_plc.IsConnected) + { + await ConnectAsync(cancellationToken); + if (_plc == null || !_plc.IsConnected) + throw new InvalidOperationException("PLC未连接"); + } + + // 2. 核心修复:DBW地址强制转short(适配16位字类型) + object writeValue = value; + if (address.Contains("DBW", StringComparison.OrdinalIgnoreCase) && value is int intVal) + { + writeValue = (short)intVal; // 写入1时自动转为short,匹配DBW类型 + } + + // 3. 移除Task.Run,直接同步写入(避免异步调度导致失效) + _plc.Write(address, writeValue); + } + catch (Exception ex) + { + Console.WriteLine($"Write error: {ex.Message}"); + throw; // 抛出异常,让上层感知写入失败(关键:不吞异常) + } + finally + { + _semaphore.Release(); + } + } private T ConvertResult(object result) diff --git a/RIZO.Service/PLCBackground/Stations/Into/PlcIntoStationService_OP80_01.cs b/RIZO.Service/PLCBackground/Stations/Into/PlcIntoStationService_OP80_01.cs index 8e1b15c..0ea0ab9 100644 --- a/RIZO.Service/PLCBackground/Stations/Into/PlcIntoStationService_OP80_01.cs +++ b/RIZO.Service/PLCBackground/Stations/Into/PlcIntoStationService_OP80_01.cs @@ -58,31 +58,42 @@ namespace RIZO.Service.PLCBackground.Stations.Into await _plcService.WriteAsync("DB1020.DBW0", 1); // 轮询进站请求信号/工位开始查询请求 - int intoStationAsk = await _plcService.ReadAsync("DB1001.DBW2000"); + int intoStationAsk = await _plcService.ReadAsync("DB1017.DBW2000"); if (intoStationAsk == 1) { // 处理进站请求 _logger.Info("Processing into station request..."); //获取产品SN码 - string productModel = await _plcService.ReadStringAsync("DB1001.DBB1000"); - string productSN = await _plcService.ReadStringAsync("DB1001.DBB1054"); + string productModel = await _plcService.ReadStringAsync("DB1017.DBB1000"); + string productSN = await _plcService.ReadStringAsync("DB1017.DBB1054"); + int ReWorkFlag = await _plcService.ReadAsync("DB1017.DBW8"); + //判断改产品是正常件还是返工件 + if (ReWorkFlag == 2) + { + + } // 获取工单 - //获取工艺路线工序 List processOperations = await Context.Queryable().LeftJoin((r, o) => r.RoutingCode == o.FkRoutingCode) .Where((r, o) => r.FkProductMaterialCode == productModel && r.Status == 1) .Select((r, o) => o).ToListAsync(); - //判断改产品是正常件还是返工件 - - + var routingcode = string.Empty; + try + { + routingcode = processOperations.First().FkRoutingCode; + } + catch + { } + if (routingcode == null || routingcode.Length == 0) + return; //插入入站请求ASK过站记录 ProductPassStationRecord ASKintoStation = new ProductPassStationRecord { ProductSN = productSN, WorkstationCode = WorkstationCode, - Routingcode = processOperations.First().FkRoutingCode, + Routingcode = routingcode, OperationCode = WorkstationCode, ProductionLifeStage = 1, // 1表示生产中 PasstationType = 0, // 0表示入站请求 @@ -93,7 +104,10 @@ namespace RIZO.Service.PLCBackground.Stations.Into await Context.Insertable(ASKintoStation).ExecuteCommandAsync(); //判断该产品是否允许进站 EntryPermissionResult result = await checkEntryPermission(productModel, productSN, WorkstationCode, processOperations); - await _plcService.WriteAsync("DB1020.DBW2000", (int)result); + //进站请求结果 + await _plcService.WriteAsync2("DB1317.DBW2000", (int)result); + //设别使能1 + await _plcService.WriteAsync2("DB1317.DBW0", 1); } await Task.Delay(_pollingInterval, stoppingToken); @@ -122,118 +136,123 @@ namespace RIZO.Service.PLCBackground.Stations.Into /// private async Task checkEntryPermission(string productModel, string productSN, string workstationCode, List processOperations) { - - EntryPermissionResult result = EntryPermissionResult.UnkownException; - - - //2上工位无记录 - - //ProcessOperation LastOperation = processOperations.Where(operation => operation.OperationSeq < processOperations.Where(it => it.OperationCode == workstationCode).Select(it => it.OperationSeq).First()).OrderByDescending(operation => operation.OperationSeq).First(); - int LastOperationSeq = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.LastOperationSeq ?? -1).First(); - ProcessOperation LastOperation = processOperations.Where(it => it.OperationSeq == LastOperationSeq).First(); - bool isExistLastOperationRecord = await DbScoped.SugarScope.CopyNew().Queryable() - .Where(it => it.ProductSN == productSN) - .Where(it => it.OperationCode == LastOperation.OperationCode) - .AnyAsync(); - if (!isExistLastOperationRecord) + try { - return EntryPermissionResult.NoRecordAtPreviousStation; - } + EntryPermissionResult result = EntryPermissionResult.UnkownException; - // 3 上工位NG 入站或者出站结果 NG - bool isExistLastOperationNG = await Context.Queryable() - .Where(it => it.ProductSN == productSN) - .Where(it => it.OperationCode == LastOperation.OperationCode) - .Where(it => it.PasstationType == 2 || it.PasstationType == 4) - .Where(it => it.ResultCode != 1) - .AnyAsync(); - if (!isExistLastOperationNG) - { - result = EntryPermissionResult.PreviousStationNG; - goto InsertPassrecord; - } + //2上工位无记录 - - // 4 扫码产品型号错误 - bool isExistproductSN = await Context.Queryable() - .Where(it => it.ProductSN == productSN).AnyAsync(); - - - bool isExistproductSNProducting = await Context.Queryable() - .Where(it => it.ProductSN == productSN && (it.ProductCurrentStatus != 1 && it.ProductCurrentStatus != 3)).AnyAsync(); - if (!isExistproductSN || !isExistproductSNProducting) - { - result = EntryPermissionResult.ProductModelError; - goto InsertPassrecord; - } - //6时间超出规定无法生产 - - - //7固化时间未到规定时间 - - int LastOperationStandardTime = processOperations.Where(operation => operation.OperationCode == LastOperation.OperationCode) - .Select(operation => operation.StandardTime??0).First(); - - - - if (LastOperationStandardTime > 0) - { - // 上一站的入站时间 和本站的请求时间差值 - DateTime LastInStationTime= await Context.Queryable() - .Where(it => it.ProductSN == productSN) - .Where(it => it.OperationCode == LastOperation.OperationCode) - .Where(it => it.PasstationType == 1) - .MaxAsync(it => it.InStationTime??DateTime.MinValue); - TimeSpan timeDiff = DateTime.Now - LastInStationTime; - double totalSeconds = timeDiff.TotalSeconds; - if(totalSeconds < LastOperationStandardTime) + //ProcessOperation LastOperation = processOperations.Where(operation => operation.OperationSeq < processOperations.Where(it => it.OperationCode == workstationCode).Select(it => it.OperationSeq).First()).OrderByDescending(operation => operation.OperationSeq).First(); + int LastOperationSeq = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.LastOperationSeq ?? -1).First(); + ProcessOperation LastOperation = processOperations.Where(it => it.OperationSeq == LastOperationSeq).First(); + bool isExistLastOperationRecord = await DbScoped.SugarScope.CopyNew().Queryable() + .Where(it => it.ProductSN == productSN) + .Where(it => it.OperationCode == LastOperation.OperationCode) + .AnyAsync(); + if (!isExistLastOperationRecord) { - result = EntryPermissionResult.CuringTimeNotReached; + return EntryPermissionResult.NoRecordAtPreviousStation; + } + + // 3 上工位NG 入站或者出站结果 NG + bool isExistLastOperationNG = await Context.Queryable() + .Where(it => it.ProductSN == productSN) + .Where(it => it.OperationCode == LastOperation.OperationCode) + .Where(it => it.PasstationType == 2 || it.PasstationType == 4) + .Where(it => it.ResultCode != 1) + .AnyAsync(); + if (!isExistLastOperationNG) + { + result = EntryPermissionResult.PreviousStationNG; goto InsertPassrecord; } - } - //12 最大重复入站次数 - int MaxRepeatEntries = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.MaxStationCount??1).First(); - if(MaxRepeatEntries>1) - { - int currentStationEntryCount = await Context.Queryable() - .Where(it => it.ProductSN == productSN) - .Where(it => it.OperationCode == workstationCode) - .Where(it => it.PasstationType == 1) - .CountAsync(); - if(currentStationEntryCount >= MaxRepeatEntries) + // 4 扫码产品型号错误 + bool isExistproductSN = await Context.Queryable() + .Where(it => it.ProductSN == productSN).AnyAsync(); + + + bool isExistproductSNProducting = await Context.Queryable() + .Where(it => it.ProductSN == productSN && (it.ProductCurrentStatus != 1 && it.ProductCurrentStatus != 3)).AnyAsync(); + if (!isExistproductSN || !isExistproductSNProducting) { - result = EntryPermissionResult.MaximumRepeatedEntries; + result = EntryPermissionResult.ProductModelError; goto InsertPassrecord; } - } + //6时间超出规定无法生产 - //OK 准许进站 - result = EntryPermissionResult.AllowIntoStation; - goto InsertPassrecord; + + //7固化时间未到规定时间 + + int LastOperationStandardTime = processOperations.Where(operation => operation.OperationCode == LastOperation.OperationCode) + .Select(operation => operation.StandardTime ?? 0).First(); + + + + if (LastOperationStandardTime > 0) + { + // 上一站的入站时间 和本站的请求时间差值 + DateTime LastInStationTime = await Context.Queryable() + .Where(it => it.ProductSN == productSN) + .Where(it => it.OperationCode == LastOperation.OperationCode) + .Where(it => it.PasstationType == 1) + .MaxAsync(it => it.InStationTime ?? DateTime.MinValue); + TimeSpan timeDiff = DateTime.Now - LastInStationTime; + double totalSeconds = timeDiff.TotalSeconds; + if (totalSeconds < LastOperationStandardTime) + { + result = EntryPermissionResult.CuringTimeNotReached; + goto InsertPassrecord; + } + + } + + //12 最大重复入站次数 + int MaxRepeatEntries = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.MaxStationCount ?? 1).First(); + if (MaxRepeatEntries > 1) + { + int currentStationEntryCount = await Context.Queryable() + .Where(it => it.ProductSN == productSN) + .Where(it => it.OperationCode == workstationCode) + .Where(it => it.PasstationType == 1) + .CountAsync(); + if (currentStationEntryCount >= MaxRepeatEntries) + { + result = EntryPermissionResult.MaximumRepeatedEntries; + goto InsertPassrecord; + } + } + + //OK 准许进站 + result = EntryPermissionResult.AllowIntoStation; + goto InsertPassrecord; InsertPassrecord: - //插入入站请求Resp过站记录 - ProductPassStationRecord RespintoStation = new ProductPassStationRecord + //插入入站请求Resp过站记录 + ProductPassStationRecord RespintoStation = new ProductPassStationRecord + { + ProductSN = productSN, + WorkstationCode = WorkstationCode, + Routingcode = processOperations.First().FkRoutingCode, + OperationCode = WorkstationCode, + ProductionLifeStage = 1, // 1表示生产中 + PasstationType = 1, // 入站完毕 + PasstationDescription = "入站完毕Resp", + EffectTime = DateTime.Now, + InStationTime = DateTime.Now, + ResultCode = (int)result, + ResultDescription = result.ToString(), + CreatedTime = DateTime.Now, + + }; + await Context.Insertable(RespintoStation).ExecuteCommandAsync(); + return result; + } + catch { - ProductSN = productSN, - WorkstationCode = WorkstationCode, - Routingcode = processOperations.First().FkRoutingCode, - OperationCode = WorkstationCode, - ProductionLifeStage = 1, // 1表示生产中 - PasstationType = 1, // 入站完毕 - PasstationDescription = "入站完毕Resp", - EffectTime = DateTime.Now, - InStationTime = DateTime.Now, - ResultCode = (int)result, - ResultDescription = result.ToString(), - CreatedTime = DateTime.Now, - - }; - await Context.Insertable(RespintoStation).ExecuteCommandAsync(); - - return result; + return EntryPermissionResult.PreviousStationDataAbnormal; + } + }