plc数据采集调试

This commit is contained in:
quowingwang 2026-02-02 14:08:46 +08:00
parent bf6a7f11b6
commit d06908a1b9
14 changed files with 289 additions and 143 deletions

View File

@ -0,0 +1,118 @@
using Infrastructure.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Security.Claims;
namespace Infrastructure
{
public static class App
{
/// <summary>
/// 全局配置文件 从容器中获取
/// </summary>
public static OptionsSetting OptionsSetting => CatchOrDefault(() => ServiceProvider?.GetService<IOptions<OptionsSetting>>()?.Value);
/// <summary>
/// 服务提供器
/// </summary>
public static IServiceProvider ServiceProvider => InternalApp.ServiceProvider;
/// <summary>
/// 获取请求上下文
/// </summary>
public static HttpContext HttpContext => CatchOrDefault(() => ServiceProvider?.GetService<IHttpContextAccessor>()?.HttpContext);
/// <summary>
/// 获取请求上下文用户
/// </summary>
public static ClaimsPrincipal User => HttpContext?.User;
/// <summary>
/// 获取用户名
/// </summary>
public static string UserName => User?.Identity?.Name;
/// <summary>
/// 获取Web主机环境
/// </summary>
public static IWebHostEnvironment WebHostEnvironment => InternalApp.WebHostEnvironment;
/// <summary>
/// 获取全局配置
/// </summary>
public static IConfiguration Configuration => CatchOrDefault(() => InternalApp.Configuration, new ConfigurationBuilder().Build());
/// <summary>
/// 获取请求生命周期的服务
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static TService GetService<TService>()
where TService : class
{
return GetService(typeof(TService)) as TService;
}
/// <summary>
/// 获取请求生命周期的服务
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object GetService(Type type)
{
return ServiceProvider.GetService(type);
}
/// <summary>
/// 获取请求生命周期的服务
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <returns></returns>
public static TService GetRequiredService<TService>()
where TService : class
{
return GetRequiredService(typeof(TService)) as TService;
}
/// <summary>
/// 获取请求生命周期的服务
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object GetRequiredService(Type type)
{
return ServiceProvider.GetRequiredService(type);
}
/// <summary>
/// 处理获取对象异常问题
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="action">获取对象委托</param>
/// <param name="defaultValue">默认值</param>
/// <returns>T</returns>
private static T CatchOrDefault<T>(Func<T> action, T defaultValue = null)
where T : class
{
try
{
return action();
}
catch
{
return defaultValue ?? null;
}
}
/// <summary>
/// 获取默认租户ID
/// </summary>
/// <returns></returns>
public static string GetCurrentTenantId()
{
var headerId = HttpContext?.Request?.Headers["tenantId"].ToString();
var claimId = User?.Claims.FirstOrDefault(f => f.Type == ClaimTypes.PrimaryGroupSid)?.Value;
return !string.IsNullOrEmpty(headerId) ? headerId : (claimId ?? "tenant0");
}
}
}

View File

@ -341,7 +341,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ {
{ "产品型号", ("DB1004.DBB1000", 48) }, // String[48] { "产品型号", ("DB1004.DBB1000", 48) }, // String[48]
{ "产品名称", ("DB1004.DBB1054", 48) }, // String[48] { "产品名称", ("DB1004.DBB1054", 48) }, // String[48]
{ "SN_1", ("DB1004.DBB2234", 40) } // String[40] - 条码(查询、上传) { "SN_1", ("DB1004.DBB2100", 40) } // String[40] - 条码(查询、上传)
}; };
private readonly Dictionary<string, string> _op058IntMap = new() private readonly Dictionary<string, string> _op058IntMap = new()
@ -352,8 +352,8 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ "失败数量", "DB1004.DBD1112" }, // DInt { "失败数量", "DB1004.DBD1112" }, // DInt
// 操作请求 // 操作请求
{ "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始0=无请求 { "工位开始查询请求", "DB1004.DBW2000" }, // Int - 1=请求开始0=无请求
{ "1#产品结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求0=无请求 { "1#产品结果保存请求", "DB1004.DBW2002" }, // Int - 1=请求0=无请求
// 产品结果 // 产品结果
{ "产品总结果", "DB1004.DBW2278" }, // Int - 1=OK2=NG { "产品总结果", "DB1004.DBW2278" }, // Int - 1=OK2=NG
@ -1397,8 +1397,13 @@ namespace RIZO.Admin.WebApi.PLC.Service
iSaveRequest = await ReadPlcIntAsync(plc, _op165IntMap["结果保存请求"]).ConfigureAwait(false); iSaveRequest = await ReadPlcIntAsync(plc, _op165IntMap["结果保存请求"]).ConfigureAwait(false);
break; break;
} }
if (iSaveRequest != 1) return (false, null, string.Empty); //写设备使能信号
if (iSaveRequest == 1) WritePlcMachineEnable(plc);
if (iSaveRequest != 1)
{
return (false, null, string.Empty);
}
else
{ {
// 优化:所有工位数据读取取消上下文切换 // 优化:所有工位数据读取取消上下文切换
prodData = plcName switch prodData = plcName switch
@ -1449,16 +1454,15 @@ namespace RIZO.Admin.WebApi.PLC.Service
}, TaskContinuationOptions.OnlyOnFaulted) }, TaskContinuationOptions.OnlyOnFaulted)
.ConfigureAwait(false); // 新增:取消上下文切换 .ConfigureAwait(false); // 新增:取消上下文切换
} }
// 个性化返回消息+写入成功返回值
var successMsg = isConnReused
? $"{plcName}生产数据读取成功(复用连接)"
: $"{plcName}生产数据读取成功(新建连接)";
WritePlcSaveRequestResult(plc, ip, plcName, prodData, "1");
_ = Task.Run(() => RecordPlcOperationResult(plcName, prodData)).ConfigureAwait(false);
return (true, prodData, successMsg);
} }
// 个性化返回消息+写入成功返回值
var successMsg = isConnReused
? $"{plcName}生产数据读取成功(复用连接)"
: $"{plcName}生产数据读取成功(新建连接)";
WritePlcSaveRequestResult(plc, ip, plcName, prodData, "1");
_ = Task.Run(() => RecordPlcOperationResult(plcName, prodData)).ConfigureAwait(false);
return (true, prodData, successMsg);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -2529,15 +2533,19 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ "1#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝扭矩"]) }, { "1#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝扭矩"]) },
{ "1#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝深度"]) }, { "1#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝深度"]) },
{ "1#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝角度"]) }, { "1#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝角度"]) },
{ "1#螺丝时间", ReadPlcRealAsync(plc, _op060IntMap["1#螺丝时间"]) },
{ "2#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝扭矩"]) }, { "2#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝扭矩"]) },
{ "2#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝深度"]) }, { "2#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝深度"]) },
{ "2#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝角度"]) }, { "2#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝角度"]) },
{ "2#螺丝时间", ReadPlcRealAsync(plc, _op060IntMap["2#螺丝时间"]) },
{ "3#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝扭矩"]) }, { "3#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝扭矩"]) },
{ "3#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝深度"]) }, { "3#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝深度"]) },
{ "3#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝角度"]) }, { "3#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝角度"]) },
{ "3#螺丝时间", ReadPlcRealAsync(plc, _op060IntMap["3#螺丝时间"]) },
{ "4#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝扭矩"]) }, { "4#螺丝扭矩", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝扭矩"]) },
{ "4#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝深度"]) }, { "4#螺丝深度", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝深度"]) },
{ "4#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝角度"]) }, { "4#螺丝角度", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝角度"]) },
{ "4#螺丝时间", ReadPlcRealAsync(plc, _op060IntMap["4#螺丝时间"]) },
{ "节拍时间", ReadPlcRealAsync(plc, _op060IntMap["节拍时间"]) } { "节拍时间", ReadPlcRealAsync(plc, _op060IntMap["节拍时间"]) }
}; };
@ -5658,8 +5666,8 @@ namespace RIZO.Admin.WebApi.PLC.Service
}; };
if (targetMap != null) if (targetMap != null)
{ {
WritePlcValue(plc, targetMap["设备使能"], "1"); //WritePlcValue(plc, targetMap["设备使能"], "1");
WritePlcValue(plc, targetMap["保存结果"], saveResult); WritePlcValue(plc, targetMap["保存结果"], saveResult);
} }
} }
catch (Exception ex) catch (Exception ex)
@ -5667,6 +5675,17 @@ namespace RIZO.Admin.WebApi.PLC.Service
} }
} }
// 提取写PLC返回值的通用方法统一处理逻辑和日志
private void WritePlcMachineEnable(Plc plc)
{
try
{
WritePlcValue(plc, _mesIntReturnMap["设备使能"], "1");
}
catch (Exception ex)
{
}
}
/// <summary> /// <summary>
/// 记录PLC过站状态 /// 记录PLC过站状态
/// </summary> /// </summary>
@ -5679,10 +5698,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
throw new ArgumentNullException(nameof(prodData), "PLC生产数据实体不能为空"); throw new ArgumentNullException(nameof(prodData), "PLC生产数据实体不能为空");
// 2. SN校验直接判断减少临时变量赋值 // 2. SN校验直接判断减少临时变量赋值
if (string.IsNullOrWhiteSpace(prodData.SN2?.Trim())) if (string.IsNullOrWhiteSpace(prodData.ProductCode?.Trim()))
return; return;
var strSN = prodData.SN2.Trim(); // 仅在非空时赋值,减少内存分配 var strSN = prodData.ProductCode.Trim(); // 仅在非空时赋值,减少内存分配
// 3. 合格状态转换(提前计算,减少后续引用开销) // 3. 合格状态转换(提前计算,减少后续引用开销)
var result = string.Equals(prodData.QualificationFlag, "1", StringComparison.OrdinalIgnoreCase) ? 1 : 0; var result = string.Equals(prodData.QualificationFlag, "1", StringComparison.OrdinalIgnoreCase) ? 1 : 0;
var now = DateTime.Now; var now = DateTime.Now;
@ -5707,10 +5725,14 @@ namespace RIZO.Admin.WebApi.PLC.Service
} }
// 补全:执行删除操作,避免重复数据(放在插入之前)
var delCount = await context.Deleteable<ProductPassStationRecord>()
.Where(it => it.ProductSN == strSN && it.WorkstationCode == plcName && it.PasstationType == 3)
.ExecuteCommandAsync();
// 5. 返工状态判断(无分配判断,直接赋值) // 5. 返工状态判断(无分配判断,直接赋值)
var productionLifeStage = string.Equals(prodData.ReworkFlag, "1", StringComparison.OrdinalIgnoreCase) ? 2 : 1; var productionLifeStage = string.Equals(prodData.ReworkFlag, "1", StringComparison.OrdinalIgnoreCase) ? 2 : 1;
// 6. 构建记录(结构体思维,减少冗余字段)
var askOutStation = new ProductPassStationRecord var askOutStation = new ProductPassStationRecord
{ {
ProductSN = strSN, ProductSN = strSN,

View File

@ -112,8 +112,14 @@ builder.Services.AddLocalization(options => options.ResourcesPath = "");
//PLC进站后台服务注册 //PLC进站后台服务注册
//builder.Services.AddHostedService<PlcOutStationService_OP07_01>(); //builder.Services.AddHostedService<PlcOutStationService_OP07_01>();
//builder.Services.AddHostedService<PlcIntoStationService_OP102>(); builder.Services.AddHostedService<PlcIntoStationService_OP057>();
builder.Services.AddHostedService<PlcIntoStationService_OP058>();
builder.Services.AddHostedService<PlcIntoStationService_OP060>();
builder.Services.AddHostedService<PlcIntoStationService_OP100>(); builder.Services.AddHostedService<PlcIntoStationService_OP100>();
builder.Services.AddHostedService<PlcIntoStationService_OP102>();
builder.Services.AddHostedService<PlcIntoStationService_OP110_1>();
builder.Services.AddHostedService<PlcIntoStationService_OP110_2>();
builder.Services.AddHostedService<PlcIntoStationService_OP110_3>();
//螺丝枪服务注册 //螺丝枪服务注册
//builder.Services.AddHostedService<PF6ScrewGunService>(); //builder.Services.AddHostedService<PF6ScrewGunService>();

View File

@ -206,7 +206,7 @@
{ {
"Id": 6, "Id": 6,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP057", "WorkStationCode": "OP057",
"WorkStationName": "OP057 压装定位销&激光打标", "WorkStationName": "OP057 压装定位销&激光打标",
"PlcType": "S71500", "PlcType": "S71500",
@ -215,14 +215,14 @@
"Heartbeat": "DB1000.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2904",
"IntoStationResp": "DB1000.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
"Id": 7, "Id": 7,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP058", "WorkStationCode": "OP058",
"WorkStationName": "OP058 压装定位销&激光打标", "WorkStationName": "OP058 压装定位销&激光打标",
"PlcType": "S71500", "PlcType": "S71500",
@ -231,13 +231,13 @@
"Heartbeat": "DB1003.DBW0", // "Heartbeat": "DB1003.DBW0", //
"IntoStationAsk": "DB1004.DBW2000", // "IntoStationAsk": "DB1004.DBW2000", //
"ProductModel": "DB1004.DBB1000", "ProductModel": "DB1004.DBB1000",
"ProductSN": "DB1004.DBB1054", "ProductSN": "DB1004.DBB2100",
"IntoStationResp": "DB1003.DBW2000" // "IntoStationResp": "DB1003.DBW2000" //
} }
}, },
{ {
"Id": 8, "Id": 8,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP060", "WorkStationCode": "OP060",
"WorkStationName": "OP060 高低压接头拧紧", "WorkStationName": "OP060 高低压接头拧紧",
"PlcType": "S71500", "PlcType": "S71500",
@ -246,7 +246,7 @@
"Heartbeat": "DB1000.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1000.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
@ -258,11 +258,11 @@
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.10.222", "IpAddress": "192.168.10.222",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB1054",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
@ -304,11 +304,11 @@
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.11.26", "IpAddress": "192.168.11.26",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB1054",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
@ -334,11 +334,11 @@
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.1.111", "IpAddress": "192.168.1.111",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1317.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1017.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1017.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1017.DBB1054", "ProductSN": "DB1001.DBB1054",
"IntoStationResp": "DB1317.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
@ -378,11 +378,11 @@
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.11.86", "IpAddress": "192.168.11.86",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB1054",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
//{ //{
@ -467,61 +467,61 @@
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.1.140", "IpAddress": "192.168.1.140",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
"Id": 19, "Id": 19,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP102", "WorkStationCode": "OP102",
"WorkStationName": "OP102 等离子处理", "WorkStationName": "OP102 等离子处理",
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.1.140", "IpAddress": "192.168.11.186",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB2100", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
"Id": 20, "Id": 20,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP110-1", "WorkStationCode": "OP110-1",
"WorkStationName": "OP110-1 点密封胶Q3-3636", "WorkStationName": "OP110-1 点密封胶Q3-3636",
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.11.201", "IpAddress": "192.168.11.201",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
"Id": 21, "Id": 21,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP110-2", "WorkStationCode": "OP110-2",
"WorkStationName": "OP110-2 盖板组装&拧紧", "WorkStationName": "OP110-2 盖板组装&拧紧",
"PlcType": "S71500", "PlcType": "S71500",
"IpAddress": "192.168.11.216", "IpAddress": "192.168.11.216",
"IntoStation": { "IntoStation": {
"Heartbeat": "DB1010.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1010.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },
{ {
"Id": 22, "Id": 22,
"isEnble": false, "isEnble": true,
"WorkStationCode": "OP110-3", "WorkStationCode": "OP110-3",
"WorkStationName": "OP110-3 盖板拧紧", "WorkStationName": "OP110-3 盖板拧紧",
"PlcType": "S71500", "PlcType": "S71500",
@ -530,7 +530,7 @@
"Heartbeat": "DB1000.DBW0", // "Heartbeat": "DB1000.DBW0", //
"IntoStationAsk": "DB1001.DBW2000", // "IntoStationAsk": "DB1001.DBW2000", //
"ProductModel": "DB1001.DBB1000", "ProductModel": "DB1001.DBB1000",
"ProductSN": "DB1001.DBB1054", "ProductSN": "DB1001.DBB2100",
"IntoStationResp": "DB1000.DBW2000" // "IntoStationResp": "DB1000.DBW2000" //
} }
}, },

View File

@ -194,93 +194,93 @@ namespace RIZO.Service.PLCBackground.Stations.Into
var LastOperationSeqObject = processOperations?.Where(operation => var LastOperationSeqObject = processOperations?.Where(operation =>
string.Equals(operation.OperationCode, workstationCode, StringComparison.OrdinalIgnoreCase)) string.Equals(operation.OperationCode, workstationCode, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault(); .FirstOrDefault();
if (LastOperationSeqObject.LastOperationSeq == 0) if (LastOperationSeqObject.LastOperationSeq != 0)
{ {
return EntryPermissionResult.NoRecordAtPreviousStation; ProcessOperation LastOperation = processOperations.Where(it => it.OperationSeq == LastOperationSeqObject.LastOperationSeq).First();
}
ProcessOperation LastOperation = processOperations.Where(it => it.OperationSeq == LastOperationSeqObject. LastOperationSeq).First();
// 2. 清理 OperationCode去除首尾空格 + 移除 \r 等不可见控制字符(兼容你之前的问题) // 2. 清理 OperationCode去除首尾空格 + 移除 \r 等不可见控制字符(兼容你之前的问题)
string cleanOperationCode = LastOperation.OperationCode string cleanOperationCode = LastOperation.OperationCode
.Replace("\r", "") // 移除回车符 .Replace("\r", "") // 移除回车符
.Replace("\n", "") // 可选:移除换行符 .Replace("\n", "") // 可选:移除换行符
.Trim(); // 移除首尾空格 .Trim(); // 移除首尾空格
productSN = productSN.Replace("\r", "").Replace("\n", "").Trim(); productSN = productSN.Replace("\r", "").Replace("\n", "").Trim();
// 3. 构建并执行真正的异步查询(补充执行方法,使 await 生效) // 3. 构建并执行真正的异步查询(补充执行方法,使 await 生效)
var ExistLastOperationRecord = await DbScoped.SugarScope.CopyNew() var ExistLastOperationRecord = await DbScoped.SugarScope.CopyNew()
.Queryable<ProductPassStationRecord>() .Queryable<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN) .Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == cleanOperationCode) // 使用清理后的字符串匹配 .Where(it => it.OperationCode == cleanOperationCode) // 使用清理后的字符串匹配
// 补充:根据需求选择合适的执行方法(二选一或其他) // 补充:根据需求选择合适的执行方法(二选一或其他)
.ToListAsync(); // 推荐:返回符合条件的所有数据(列表) .ToListAsync(); // 推荐:返回符合条件的所有数据(列表)
// .FirstOrDefaultAsync(); // 若只需返回第一条数据,用这个(无匹配返回 null // .FirstOrDefaultAsync(); // 若只需返回第一条数据,用这个(无匹配返回 null
// bool isExistLastOperationRecord = false; // bool isExistLastOperationRecord = false;
if (ExistLastOperationRecord != null &&ExistLastOperationRecord.Count()==0) if (ExistLastOperationRecord != null && ExistLastOperationRecord.Count() == 0)
{
return EntryPermissionResult.NoRecordAtPreviousStation;
}
//// 3 上工位NG 入站或者出站结果 NG
//bool isExistLastOperationNG = Context.Queryable<ProductPassStationRecord>()
// .Where(it => it.ProductSN == productSN)
// .Where(it => it.OperationCode == cleanOperationCode)
// .Where(it => it.PasstationType == 3)
// .Where(it => it.ResultCode == 1)
// .Any();
// 3 上工位NG 入站或者出站结果 NG
var ExistLastOperationNG = Context.Queryable<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == cleanOperationCode)
.Where(it => it.PasstationType == 3)
.Where(it => it.ResultCode == 1).ToList();
if (ExistLastOperationNG.Count() == 0 )
{
result = EntryPermissionResult.PreviousStationNG;
goto InsertPassrecord;
}
// 4 扫码产品型号错误
//bool isExistproductSN = await Context.Queryable<ProductLifecycle>()
// .Where(it => it.ProductSN == productSN).AnyAsync();
//bool isExistproductSNProducting = await Context.Queryable<ProductLifecycle>()
// .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<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == cleanOperationCode)
.Where(it => it.PasstationType == 3)
.MaxAsync(it => it.OutStationTime??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 = Context.Queryable<ProductPassStationRecord>()
// .Where(it => it.ProductSN == productSN)
// .Where(it => it.OperationCode == cleanOperationCode)
// .Where(it => it.PasstationType == 3)
// .Where(it => it.ResultCode == 1)
// .Any();
// 3 上工位NG 入站或者出站结果 NG
var ExistLastOperationNG = Context.Queryable<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == cleanOperationCode)
.Where(it => it.PasstationType == 3)
.Where(it => it.ResultCode == 1).ToList();
if (ExistLastOperationNG.Count() == 0)
{
result = EntryPermissionResult.PreviousStationNG;
goto InsertPassrecord; goto InsertPassrecord;
} }
// 4 扫码产品型号错误
//bool isExistproductSN = await Context.Queryable<ProductLifecycle>()
// .Where(it => it.ProductSN == productSN).AnyAsync();
//bool isExistproductSNProducting = await Context.Queryable<ProductLifecycle>()
// .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<ProductPassStationRecord>()
.Where(it => it.ProductSN == productSN)
.Where(it => it.OperationCode == cleanOperationCode)
.Where(it => it.PasstationType == 3)
.MaxAsync(it => it.OutStationTime ?? DateTime.MinValue);
TimeSpan timeDiff = DateTime.Now - LastInStationTime;
double totalSeconds = timeDiff.TotalSeconds;
if (totalSeconds < LastOperationStandardTime)
{
result = EntryPermissionResult.CuringTimeNotReached;
goto InsertPassrecord;
}
}
} }
//12 最大重复入站次数 //12 最大重复入站次数
int MaxRepeatEntries = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.MaxStationCount??1).First(); int MaxRepeatEntries = processOperations.Where(operation => operation.OperationCode == workstationCode).Select(operation => operation.MaxStationCount??1).First();

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP070_2(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP070_2(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP70_2"; WorkstationCode = "OP070-2";
} }
} }

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP070_3(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP070_3(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP070_3"; WorkstationCode = "OP070-3";
} }
} }

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP080_2(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP080_2(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP080_2"; WorkstationCode = "OP080-2";
} }
} }

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
//{ //{
// public PlcIntoStationService_OP080_3(IOptions<OptionsSetting> options) : base(options) // public PlcIntoStationService_OP080_3(IOptions<OptionsSetting> options) : base(options)
// { // {
// WorkstationCode = "OP080_3"; // WorkstationCode = "OP080-3";
// } // }
//} //}

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP110_1(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP110_1(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP110_1"; WorkstationCode = "OP110-1";
} }
} }

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP110_2(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP110_2(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP110_2"; WorkstationCode = "OP110-2";
} }
} }

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP110_3(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP110_3(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP110_3"; WorkstationCode = "OP110-3";
} }
} }

View File

@ -40,7 +40,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
Context = DbScoped.SugarScope.CopyNew(); Context = DbScoped.SugarScope.CopyNew();
_optionsSetting= options.Value; _optionsSetting= options.Value;
plcSetting = _optionsSetting.PlcSettings.Where(it=>it.WorkStationCode== "OP70_01").First(); plcSetting = _optionsSetting.PlcSettings.Where(it=>it.WorkStationCode== "OP070-1").First();
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)

View File

@ -29,7 +29,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
{ {
public PlcIntoStationService_OP70_02(IOptions<OptionsSetting> options) : base(options) public PlcIntoStationService_OP70_02(IOptions<OptionsSetting> options) : base(options)
{ {
WorkstationCode = "OP70_02"; WorkstationCode = "OP070-2";
} }
} }