PLC进站请求BUG 修改

This commit is contained in:
quowingwang 2026-01-28 20:46:02 +08:00
parent 6d6d8c6e09
commit e8116783c8
3 changed files with 160 additions and 108 deletions

View File

@ -112,7 +112,7 @@ builder.Services.AddLocalization(options => options.ResourcesPath = "");
//builder.Services.AddHostedService<PlcOutStationService_OP07_01>(); //builder.Services.AddHostedService<PlcOutStationService_OP07_01>();
//builder.Services.AddHostedService<PlcIntoStationService_OP70_01>(); //builder.Services.AddHostedService<PlcIntoStationService_OP70_01>();
builder.Services.AddHostedService<PlcIntoStationService_OP80_01>();
// 在应用程序启动的最开始处调用 // 在应用程序启动的最开始处调用
var app = builder.Build(); var app = builder.Build();

View File

@ -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<T>(object result) private T ConvertResult<T>(object result)

View File

@ -58,31 +58,42 @@ namespace RIZO.Service.PLCBackground.Stations.Into
await _plcService.WriteAsync("DB1020.DBW0", 1); await _plcService.WriteAsync("DB1020.DBW0", 1);
// 轮询进站请求信号/工位开始查询请求 // 轮询进站请求信号/工位开始查询请求
int intoStationAsk = await _plcService.ReadAsync<int>("DB1001.DBW2000"); int intoStationAsk = await _plcService.ReadAsync<int>("DB1017.DBW2000");
if (intoStationAsk == 1) if (intoStationAsk == 1)
{ {
// 处理进站请求 // 处理进站请求
_logger.Info("Processing into station request..."); _logger.Info("Processing into station request...");
//获取产品SN码 //获取产品SN码
string productModel = await _plcService.ReadStringAsync("DB1001.DBB1000"); string productModel = await _plcService.ReadStringAsync("DB1017.DBB1000");
string productSN = await _plcService.ReadStringAsync("DB1001.DBB1054"); string productSN = await _plcService.ReadStringAsync("DB1017.DBB1054");
int ReWorkFlag = await _plcService.ReadAsync<int>("DB1017.DBW8");
//判断改产品是正常件还是返工件
if (ReWorkFlag == 2)
{
}
// 获取工单 // 获取工单
//获取工艺路线工序 //获取工艺路线工序
List<ProcessOperation> processOperations = await Context.Queryable<ProcessRouting>().LeftJoin<ProcessOperation>((r, o) => r.RoutingCode == o.FkRoutingCode) List<ProcessOperation> processOperations = await Context.Queryable<ProcessRouting>().LeftJoin<ProcessOperation>((r, o) => r.RoutingCode == o.FkRoutingCode)
.Where((r, o) => r.FkProductMaterialCode == productModel && r.Status == 1) .Where((r, o) => r.FkProductMaterialCode == productModel && r.Status == 1)
.Select((r, o) => o).ToListAsync(); .Select((r, o) => o).ToListAsync();
//判断改产品是正常件还是返工件 var routingcode = string.Empty;
try
{
routingcode = processOperations.First().FkRoutingCode;
}
catch
{ }
if (routingcode == null || routingcode.Length == 0)
return;
//插入入站请求ASK过站记录 //插入入站请求ASK过站记录
ProductPassStationRecord ASKintoStation = new ProductPassStationRecord ProductPassStationRecord ASKintoStation = new ProductPassStationRecord
{ {
ProductSN = productSN, ProductSN = productSN,
WorkstationCode = WorkstationCode, WorkstationCode = WorkstationCode,
Routingcode = processOperations.First().FkRoutingCode, Routingcode = routingcode,
OperationCode = WorkstationCode, OperationCode = WorkstationCode,
ProductionLifeStage = 1, // 1表示生产中 ProductionLifeStage = 1, // 1表示生产中
PasstationType = 0, // 0表示入站请求 PasstationType = 0, // 0表示入站请求
@ -93,7 +104,10 @@ namespace RIZO.Service.PLCBackground.Stations.Into
await Context.Insertable(ASKintoStation).ExecuteCommandAsync(); await Context.Insertable(ASKintoStation).ExecuteCommandAsync();
//判断该产品是否允许进站 //判断该产品是否允许进站
EntryPermissionResult result = await checkEntryPermission(productModel, productSN, WorkstationCode, processOperations); 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); await Task.Delay(_pollingInterval, stoppingToken);
@ -122,118 +136,123 @@ namespace RIZO.Service.PLCBackground.Stations.Into
/// <returns></returns> /// <returns></returns>
private async Task<EntryPermissionResult> checkEntryPermission(string productModel, string productSN, string workstationCode, List<ProcessOperation> processOperations) private async Task<EntryPermissionResult> checkEntryPermission(string productModel, string productSN, string workstationCode, List<ProcessOperation> processOperations)
{ {
try
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<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == LastOperation.OperationCode)
.AnyAsync();
if (!isExistLastOperationRecord)
{ {
return EntryPermissionResult.NoRecordAtPreviousStation; EntryPermissionResult result = EntryPermissionResult.UnkownException;
}
// 3 上工位NG 入站或者出站结果 NG //2上工位无记录
bool isExistLastOperationNG = await Context.Queryable<ProductPassStationRecord>()
.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;
}
//ProcessOperation LastOperation = processOperations.Where(operation => operation.OperationSeq < processOperations.Where(it => it.OperationCode == workstationCode).Select(it => it.OperationSeq).First()).OrderByDescending(operation => operation.OperationSeq).First();
// 4 扫码产品型号错误 int LastOperationSeq = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.LastOperationSeq ?? -1).First();
bool isExistproductSN = await Context.Queryable<ProductLifecycle>() ProcessOperation LastOperation = processOperations.Where(it => it.OperationSeq == LastOperationSeq).First();
.Where(it => it.ProductSN == productSN).AnyAsync(); bool isExistLastOperationRecord = await DbScoped.SugarScope.CopyNew().Queryable<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == LastOperation.OperationCode)
bool isExistproductSNProducting = await Context.Queryable<ProductLifecycle>() .AnyAsync();
.Where(it => it.ProductSN == productSN && (it.ProductCurrentStatus != 1 && it.ProductCurrentStatus != 3)).AnyAsync(); if (!isExistLastOperationRecord)
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<ProductPassStationRecord>()
.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; return EntryPermissionResult.NoRecordAtPreviousStation;
}
// 3 上工位NG 入站或者出站结果 NG
bool isExistLastOperationNG = await Context.Queryable<ProductPassStationRecord>()
.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; goto InsertPassrecord;
} }
}
//12 最大重复入站次数 // 4 扫码产品型号错误
int MaxRepeatEntries = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.MaxStationCount??1).First(); bool isExistproductSN = await Context.Queryable<ProductLifecycle>()
if(MaxRepeatEntries>1) .Where(it => it.ProductSN == productSN).AnyAsync();
{
int currentStationEntryCount = await Context.Queryable<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN) bool isExistproductSNProducting = await Context.Queryable<ProductLifecycle>()
.Where(it => it.OperationCode == workstationCode) .Where(it => it.ProductSN == productSN && (it.ProductCurrentStatus != 1 && it.ProductCurrentStatus != 3)).AnyAsync();
.Where(it => it.PasstationType == 1) if (!isExistproductSN || !isExistproductSNProducting)
.CountAsync();
if(currentStationEntryCount >= MaxRepeatEntries)
{ {
result = EntryPermissionResult.MaximumRepeatedEntries; result = EntryPermissionResult.ProductModelError;
goto InsertPassrecord; goto InsertPassrecord;
} }
} //6时间超出规定无法生产
//OK 准许进站
result = EntryPermissionResult.AllowIntoStation; //7固化时间未到规定时间
goto InsertPassrecord;
int LastOperationStandardTime = processOperations.Where(operation => operation.OperationCode == LastOperation.OperationCode)
.Select(operation => operation.StandardTime ?? 0).First();
if (LastOperationStandardTime > 0)
{
// 上一站的入站时间 和本站的请求时间差值
DateTime LastInStationTime = await Context.Queryable<ProductPassStationRecord>()
.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<ProductPassStationRecord>()
.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: InsertPassrecord:
//插入入站请求Resp过站记录 //插入入站请求Resp过站记录
ProductPassStationRecord RespintoStation = new ProductPassStationRecord 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, return EntryPermissionResult.PreviousStationDataAbnormal;
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;
} }