PLC数采
This commit is contained in:
parent
da16fed4dc
commit
2c8e09d794
@ -12,6 +12,7 @@ using S7.Net;
|
||||
using SqlSugar;
|
||||
using SqlSugar.IOC;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -41,11 +42,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
// 先在类中添加2个核心优化字段(支撑高频访问)
|
||||
private readonly SemaphoreSlim _concurrencySemaphore = new SemaphoreSlim(15, 50); // 限制20并发(适配50台PLC)
|
||||
private readonly ConcurrentDictionary<string, (Plc Client, DateTime LastUsedTime)> _plcConnPool = new(); // 连接池
|
||||
private readonly SqlSugarClient Context;
|
||||
public PlcService()
|
||||
{
|
||||
Context = DbScoped.SugarScope.CopyNew();
|
||||
}
|
||||
#region PLC地址块儿映射
|
||||
//MES返回PLC请求映射
|
||||
private readonly Dictionary<string, string> _mesIntReturnMap = new()
|
||||
@ -615,36 +611,36 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
// OP085 专属地址映射(自动上料到波峰焊工位,DB1001)
|
||||
private readonly Dictionary<string, (string Addr, int Len)> _op085StringMap = new()
|
||||
{
|
||||
{ "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
|
||||
{ "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
|
||||
{ "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
|
||||
{ "波峰焊托盘条码", ("DB1001.DBB2070", 40) }, // String[40]
|
||||
{ "穴位1产品SN", ("DB1001.DBB2486", 40) }, // String[40]
|
||||
{ "穴位2产品SN", ("DB1001.DBB2528", 40) }, // String[40]
|
||||
{ "穴位3产品SN", ("DB1001.DBB2570", 40) }, // String[40]
|
||||
{ "穴位4产品SN", ("DB1001.DBB2612", 40) } // String[40]
|
||||
{ "报警信息", ("DB1030.DBB58", 48) }, // Array[1..48] of Byte
|
||||
{ "产品型号", ("DB1030.DBB1000", 48) }, // String[48]
|
||||
{ "产品名称", ("DB1030.DBB1054", 48) }, // String[48]
|
||||
{ "波峰焊托盘条码", ("DB1030.DBB2070", 40) }, // String[40]
|
||||
{ "穴位1产品SN", ("DB1030.DBB2486", 40) }, // String[40]
|
||||
{ "穴位2产品SN", ("DB1030.DBB2528", 40) }, // String[40]
|
||||
{ "穴位3产品SN", ("DB1030.DBB2570", 40) }, // String[40]
|
||||
{ "穴位4产品SN", ("DB1030.DBB2612", 40) } // String[40]
|
||||
};
|
||||
|
||||
private readonly Dictionary<string, string> _op085IntMap = new()
|
||||
{
|
||||
// 基础状态
|
||||
{ "运行状态", "DB1001.DBW0" }, // Int - 1=空闲,2=运行中,3=故障
|
||||
{ "设备模式", "DB1001.DBW2" }, // Int - 1=空模式;2=手动;4=初始化;8=自动;16=CycleStop
|
||||
{ "设备在线状态", "DB1001.DBW4" }, // Int - 1=离线,0=在线
|
||||
{ "ByPass", "DB1001.DBW6" }, // Int - 1=ByPass,0=正常模式
|
||||
{ "生产模式", "DB1001.DBW8" }, // Int - 1=点检,2=返工,4=样件,5=正常
|
||||
{ "运行状态", "DB1030.DBW0" }, // Int - 1=空闲,2=运行中,3=故障
|
||||
{ "设备模式", "DB1030.DBW2" }, // Int - 1=空模式;2=手动;4=初始化;8=自动;16=CycleStop
|
||||
{ "设备在线状态", "DB1030.DBW4" }, // Int - 1=离线,0=在线
|
||||
{ "ByPass", "DB1030.DBW6" }, // Int - 1=ByPass,0=正常模式
|
||||
{ "生产模式", "DB1030.DBW8" }, // Int - 1=点检,2=返工,4=样件,5=正常
|
||||
|
||||
// 产量数据
|
||||
{ "实际产量", "DB1001.DBD1104" }, // DInt
|
||||
{ "合格数量", "DB1001.DBD1108" }, // DInt
|
||||
{ "失败数量", "DB1001.DBD1112" }, // DInt
|
||||
{ "实际产量", "DB1030.DBD1104" }, // DInt
|
||||
{ "合格数量", "DB1030.DBD1108" }, // DInt
|
||||
{ "失败数量", "DB1030.DBD1112" }, // DInt
|
||||
|
||||
// 操作请求
|
||||
{ "保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
|
||||
{ "线体托盘号", "DB1001.DBW2070" }, // Int
|
||||
{ "保存请求", "DB1030.DBW2002" }, // Int - 1=请求开始,0=无请求
|
||||
{ "线体托盘号", "DB1030.DBW2070" }, // Int
|
||||
|
||||
// 工艺参数
|
||||
{ "节拍时间", "DB1001.DBD2242" } // Real
|
||||
{ "节拍时间", "DB1030.DBD2242" } // Real
|
||||
};
|
||||
|
||||
// OP100 专属地址映射(手动上料壳体&盖板工位,DB1001)
|
||||
@ -1344,7 +1340,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
? $"{plcName}生产数据读取成功(复用连接)"
|
||||
: $"{plcName}生产数据读取成功(新建连接)";
|
||||
WritePlcSaveRequestResult(plc, ip, plcName, prodData, "1");
|
||||
_ = Task.Run(() => RecordPlcOperationResult(plcName, prodData)).ConfigureAwait(false);
|
||||
_ = Task.Run(() => RecordPlcOperationResult(plcName, prodData)).ConfigureAwait(false);
|
||||
return (true, prodData, successMsg);
|
||||
|
||||
}
|
||||
@ -1403,11 +1399,17 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var taskTrayNo = ReadPlcIntAsync(plc, _op020_2IntMap["托盘号"]);
|
||||
var taskTotalResult = ReadPlcIntAsync(plc, _op020_2IntMap["总结果"]);
|
||||
|
||||
// DInt任务(单独提取,避免字典开销)
|
||||
var taskActualOutput = ReadPlcIntAsync(plc, _op050IntMap["实际产量"]);
|
||||
var taskQualifiedQty = ReadPlcIntAsync(plc, _op050IntMap["合格数量"]);
|
||||
var taskFailedQty = ReadPlcIntAsync(plc, _op050IntMap["失败数量"]);
|
||||
|
||||
|
||||
// 1.3 等待所有并行任务完成(关键:耗时=最慢的单个读取任务,而非总和)
|
||||
await Task.WhenAll(
|
||||
taskProductModel, taskProductName, taskSN,
|
||||
taskRunStatus, taskMachineModel, taskOnlineStatus,
|
||||
taskProduceModel, taskTrayNo, taskTotalResult);
|
||||
taskProduceModel, taskTrayNo, taskTotalResult, taskActualOutput, taskQualifiedQty, taskFailedQty);
|
||||
|
||||
// 2. 获取读取结果(带空值兜底,避免后续空引用)
|
||||
string productModel = await taskProductModel ?? string.Empty;
|
||||
@ -1419,6 +1421,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int produceModel = await taskProduceModel;
|
||||
int trayNo = await taskTrayNo;
|
||||
int totalResult = await taskTotalResult;
|
||||
int actualOutput = await taskActualOutput;
|
||||
int qualifiedQty = await taskQualifiedQty;
|
||||
int failedQty = await taskFailedQty;
|
||||
|
||||
// 3. 异步复位上传请求(非阻塞,不影响数据读取效率)
|
||||
_ = ResetUploadRequestAsync(plc, ip, _op020_2IntMap["上传请求"]);
|
||||
@ -1438,9 +1443,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
string onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
|
||||
string qualificationFlag = totalResult switch { 1 => "1", 2 => "0", _ => totalResult.ToString() };
|
||||
|
||||
// 调试日志(优化:使用StringBuilder减少拼接开销,高频场景更友好)
|
||||
Console.WriteLine($"OP020-2({ip})读取结果:产品型号={productModel},运行状态={runStatusDesc},总结果={qualificationFlag}");
|
||||
|
||||
// 5. 构建数据实体(优化:减少Trim/空值判断,提前兜底)
|
||||
return new PlcProductionData
|
||||
{
|
||||
@ -1460,7 +1462,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
Runstatus = runStatus,
|
||||
OnlineStatus = onlineStatusDesc,
|
||||
ProduceModel = produceModelDesc,
|
||||
TrayNo = trayNo.ToString(), // int转string开销可忽略,无需优化
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
TrayNo = trayNo.ToString(),
|
||||
CreatedBy = "PLC",
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
@ -1494,8 +1499,13 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var taskOnlineStatus = ReadPlcIntAsync(plc, _op020_3IntMap["设备在线状态"]);
|
||||
var taskProduceModel = ReadPlcIntAsync(plc, _op020_3IntMap["生产模式"]);
|
||||
|
||||
// DInt任务(单独提取,避免字典开销)
|
||||
var taskActualOutput = ReadPlcIntAsync(plc, _op050IntMap["实际产量"]);
|
||||
var taskQualifiedQty = ReadPlcIntAsync(plc, _op050IntMap["合格数量"]);
|
||||
var taskFailedQty = ReadPlcIntAsync(plc, _op050IntMap["失败数量"]);
|
||||
|
||||
// 步骤2:等待所有任务并行完成(耗时=最慢的单个读取任务,而非总和)
|
||||
await Task.WhenAll(taskRunStatus, taskMachineModel, taskOnlineStatus, taskProduceModel);
|
||||
await Task.WhenAll(taskRunStatus, taskMachineModel, taskOnlineStatus, taskProduceModel, taskActualOutput, taskQualifiedQty, taskFailedQty);
|
||||
|
||||
// 步骤3:获取结果(带await确保值已返回,无需额外判空)
|
||||
int runStatus = await taskRunStatus;
|
||||
@ -1503,6 +1513,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int onlineStatus = await taskOnlineStatus;
|
||||
int produceModel = await taskProduceModel;
|
||||
|
||||
int actualOutput = await taskActualOutput;
|
||||
int qualifiedQty = await taskQualifiedQty;
|
||||
int failedQty = await taskFailedQty;
|
||||
|
||||
// 2. 业务逻辑计算(优化:常量复用+减少冗余计算)
|
||||
var reworkFlag = produceModel == 4 ? "1" : "0";
|
||||
|
||||
@ -1539,7 +1553,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
LineCode = "line2",
|
||||
WorkstationCode = workstationCode,
|
||||
WorkstationName = "热铆", // 补充工站名称
|
||||
// 状态字段:直接赋值,无冗余转换
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ReworkFlag = reworkFlag,
|
||||
Automanual = machineModel,
|
||||
Runstatus = runStatus,
|
||||
@ -1598,10 +1614,19 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
{ "产品4结果", ReadPlcIntAsync(plc, _op020_4IntMap["产品4结果"]) }
|
||||
};
|
||||
|
||||
// DInt(双整数)读取任务(复用ReadPlcIntAsync,PLC底层兼容DInt转int)
|
||||
var dIntReadTasks = new Dictionary<string, Task<int>>
|
||||
{
|
||||
{ "实际产量", ReadPlcIntAsync(plc, _op050IntMap["实际产量"]) },
|
||||
{ "合格数量", ReadPlcIntAsync(plc, _op050IntMap["合格数量"]) },
|
||||
{ "失败数量", ReadPlcIntAsync(plc, _op050IntMap["失败数量"]) }
|
||||
};
|
||||
|
||||
// 2. 并行等待所有读取任务完成(合并任务列表,单次WaitAll提升效率)
|
||||
var allTasks = new List<Task>();
|
||||
allTasks.AddRange(stringReadTasks.Values);
|
||||
allTasks.AddRange(intReadTasks.Values);
|
||||
allTasks.AddRange(dIntReadTasks.Values);
|
||||
await Task.WhenAll(allTasks).ConfigureAwait(false);
|
||||
|
||||
// 3. 提取读取结果(直接取值+空值兜底,减少await重复调用)
|
||||
@ -1624,6 +1649,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int product3Result = intReadTasks["产品3结果"].Result;
|
||||
int product4Result = intReadTasks["产品4结果"].Result;
|
||||
|
||||
int actualOutput = dIntReadTasks["实际产量"].Result;
|
||||
int qualifiedQty = dIntReadTasks["合格数量"].Result;
|
||||
int failedQty = dIntReadTasks["失败数量"].Result;
|
||||
|
||||
// 4. 业务逻辑转换(极简逻辑,仅保留必要转换)
|
||||
string reworkFlag = produceModel == 4 ? "1" : "0";
|
||||
@ -1668,6 +1696,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
Product4Result = product1Result.ToString(),
|
||||
SN1 = product1SN,
|
||||
SN2 = product2SN,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
QualificationFlag = qualificationFlag
|
||||
};
|
||||
}
|
||||
@ -1755,6 +1786,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int byPass = intReadTasks["ByPass"].Result;
|
||||
int produceModel = intReadTasks["生产模式"].Result;
|
||||
int trayNo = intReadTasks["托盘号"].Result;
|
||||
|
||||
int actualOutput = dIntReadTasks["实际产量"].Result;
|
||||
int qualifiedQty = dIntReadTasks["合格数量"].Result;
|
||||
int failedQty = dIntReadTasks["失败数量"].Result;
|
||||
@ -1927,7 +1959,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
TrayNo = string.Empty,
|
||||
CreatedBy = "PLC",
|
||||
CreatedTime = DateTime.Now,
|
||||
// 产量/节拍核心字段
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ProductionCycle = (int)Math.Round(cycleTime), // 节拍时间转整数秒
|
||||
QualificationFlag = qualificationFlag,
|
||||
// 备注记录产量信息(便于排查)
|
||||
@ -1978,9 +2012,18 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
{ "托盘号", ReadPlcIntAsync(plc, _op051ScanIntMap["托盘号"]) }
|
||||
};
|
||||
|
||||
// DInt(双整数)读取任务(复用ReadPlcIntAsync,PLC底层兼容DInt转int)
|
||||
var dIntReadTasks = new Dictionary<string, Task<int>>
|
||||
{
|
||||
{ "实际产量", ReadPlcIntAsync(plc, _op050IntMap["实际产量"]) },
|
||||
{ "合格数量", ReadPlcIntAsync(plc, _op050IntMap["合格数量"]) },
|
||||
{ "失败数量", ReadPlcIntAsync(plc, _op050IntMap["失败数量"]) }
|
||||
};
|
||||
|
||||
// 2. 并行等待所有任务完成(单次WaitAll,最小化等待时间)
|
||||
var allTasks = new List<Task>();
|
||||
allTasks.AddRange(stringTasks.Values);
|
||||
allTasks.AddRange(dIntReadTasks.Values);
|
||||
allTasks.AddRange(intTasks.Values);
|
||||
await Task.WhenAll(allTasks).ConfigureAwait(false);
|
||||
|
||||
@ -2000,6 +2043,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var uploadRequest = intTasks["上传结果请求"].Result;
|
||||
var trayNo = intTasks["托盘号"].Result.ToString(); // 转换为字符串,适配实体字段
|
||||
|
||||
int actualOutput = dIntReadTasks["实际产量"].Result;
|
||||
int qualifiedQty = dIntReadTasks["合格数量"].Result;
|
||||
int failedQty = dIntReadTasks["失败数量"].Result;
|
||||
|
||||
// 4. 核心逻辑转换(极简表达式,适配扫码工位业务)
|
||||
var reworkFlag = produceModel == 4 ? "1" : "0"; // 4=返工模式→1,其他→0
|
||||
var produceModelDesc = produceModel switch
|
||||
@ -2040,6 +2087,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
Product2SN = sn2,
|
||||
Product3SN = sn3,
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
CreatedBy = "PLC",
|
||||
CreatedTime = now,
|
||||
};
|
||||
@ -2178,6 +2228,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
Product1Result = pin1Result.ToString(),
|
||||
Product2Result = pin2Result.ToString(),
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ProductionCycle = (int)Math.Round(cycleTime),
|
||||
|
||||
};
|
||||
@ -2268,6 +2321,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
PinPressure1 = pressure.ToString(),
|
||||
PinStroke1 = stroke.ToString(),
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ProductionCycle = (int)Math.Round(cycleTime),
|
||||
CreatedBy = "PLC_System",
|
||||
CreatedTime = now,
|
||||
@ -2353,6 +2409,8 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var onlineStatus = intTasks["设备在线状态"].Result;
|
||||
var produceModel = intTasks["生产模式"].Result;
|
||||
var actualOutput = intTasks["实际产量"].Result;
|
||||
var qualifiedQty = intTasks["合格数量"].Result;
|
||||
var failedQty = intTasks["失败数量"].Result;
|
||||
var productTotalResult = intTasks["产品总结果"].Result;
|
||||
var screw1Result = intTasks["1#螺丝结果"].Result;
|
||||
var screw2Result = intTasks["2#螺丝结果"].Result;
|
||||
@ -2408,6 +2466,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
OnlineStatus = onlineStatusDesc,
|
||||
ProduceModel = produceModelDesc,
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ProductionCycle = (int)Math.Round(cycleTime),
|
||||
CreatedBy = "PLC",
|
||||
CreatedTime = now,
|
||||
@ -2482,7 +2543,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var taskTrayNo = ReadPlcIntAsync(plc, _op070_1IntMap["托盘号"]);
|
||||
var taskCameraResult = ReadPlcIntAsync(plc, _op070_1IntMap["相机结果"]);
|
||||
var taskStationResult = ReadPlcIntAsync(plc, _op070_1IntMap["站位结果"]);
|
||||
|
||||
// DInt任务(单独提取,避免字典开销)
|
||||
var taskActualOutput = ReadPlcIntAsync(plc, _op050IntMap["实际产量"]);
|
||||
var taskQualifiedQty = ReadPlcIntAsync(plc, _op050IntMap["合格数量"]);
|
||||
var taskFailedQty = ReadPlcIntAsync(plc, _op050IntMap["失败数量"]);
|
||||
// ========== Real字段并行任务 ==========
|
||||
var taskCycleTime = ReadPlcRealAsync(plc, _op070_1IntMap["节拍时间"]);
|
||||
|
||||
@ -2494,7 +2558,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
taskRunStatus, taskMachineModel, taskOnlineStatus, taskByPass, taskProduceModel,
|
||||
taskTrayNo, taskCameraResult, taskStationResult,
|
||||
// Real任务
|
||||
taskCycleTime);
|
||||
taskCycleTime,
|
||||
// DInt任务
|
||||
taskActualOutput, taskQualifiedQty, taskFailedQty);
|
||||
|
||||
// 3. 获取并行读取结果(带空值兜底,避免后续空引用)
|
||||
// 字符串字段
|
||||
@ -2513,10 +2579,14 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int trayNo = await taskTrayNo;
|
||||
int cameraResult = await taskCameraResult;
|
||||
int stationResult = await taskStationResult;
|
||||
int actualOutput = await taskActualOutput;
|
||||
int qualifiedQty = await taskQualifiedQty;
|
||||
int failedQty = await taskFailedQty;
|
||||
|
||||
// Real字段
|
||||
float cycleTime = await taskCycleTime;
|
||||
|
||||
|
||||
// 4. 异步复位保存请求(非阻塞,不影响读取效率)
|
||||
//_ = ResetSaveRequestAsync(plc, ip, _op070_1IntMap["保存请求"]);
|
||||
|
||||
@ -2553,6 +2623,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
SN1 = sn1,
|
||||
SN2 = sn2,
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ReworkFlag = reworkFlag,
|
||||
Automanual = machineModel,
|
||||
Runstatus = runStatus,
|
||||
@ -2609,6 +2682,11 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
// ========== Real字段并行任务 ==========
|
||||
var taskCycleTime = ReadPlcRealAsync(plc, _op075IntMap["节拍时间"]);
|
||||
|
||||
// DInt任务(单独提取,避免字典开销)
|
||||
var taskActualOutput = ReadPlcIntAsync(plc, _op050IntMap["实际产量"]);
|
||||
var taskQualifiedQty = ReadPlcIntAsync(plc, _op050IntMap["合格数量"]);
|
||||
var taskFailedQty = ReadPlcIntAsync(plc, _op050IntMap["失败数量"]);
|
||||
|
||||
// 2. 等待所有并行任务完成(核心:耗时=最慢的单个读取任务,而非总和)
|
||||
await Task.WhenAll(
|
||||
// 字符串任务
|
||||
@ -2617,7 +2695,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
taskRunStatus, taskMachineModel, taskOnlineStatus, taskByPass, taskProduceModel,
|
||||
taskTrayNo, taskStationResult,
|
||||
// Real任务
|
||||
taskCycleTime);
|
||||
taskCycleTime
|
||||
// DInt任务
|
||||
, taskActualOutput, taskQualifiedQty, taskFailedQty
|
||||
);
|
||||
|
||||
// 3. 获取并行读取结果(带空值兜底,避免后续空引用)
|
||||
// 字符串字段
|
||||
@ -2636,7 +2717,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
int produceModel = await taskProduceModel;
|
||||
int trayNo = await taskTrayNo;
|
||||
int stationResult = await taskStationResult;
|
||||
|
||||
int actualOutput = await taskActualOutput;
|
||||
int qualifiedQty = await taskQualifiedQty;
|
||||
int failedQty = await taskFailedQty;
|
||||
// Real字段
|
||||
float cycleTime = await taskCycleTime;
|
||||
|
||||
@ -2676,6 +2759,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
SN2 = sn2,
|
||||
ChipSN = chipsn, // 保留芯片SN独有字段
|
||||
QualificationFlag = qualificationFlag,
|
||||
ActualOutQty = actualOutput.ToString(),
|
||||
QualifiedQty = qualifiedQty.ToString(),
|
||||
FailedQty = failedQty.ToString(),
|
||||
ReworkFlag = reworkFlag,
|
||||
Automanual = machineModel,
|
||||
Runstatus = runStatus,
|
||||
@ -2690,16 +2776,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 增强异常日志:包含堆栈,便于定位问题
|
||||
Console.WriteLine($"OP075({ip})数据读取异常:{ex.Message}\n{ex.StackTrace}");
|
||||
Console.WriteLine($"OP075({ip})数据读取异常:{ex.Message}");
|
||||
// 异常时返回基础实体,避免业务空引用
|
||||
return new PlcProductionData
|
||||
{
|
||||
PlcIp = ip,
|
||||
WorkstationCode = workstationCode,
|
||||
CreatedBy = "PLC",
|
||||
CreatedTime = DateTime.Now,
|
||||
OnlineStatus = "读取异常"
|
||||
};
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5479,17 +5558,22 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
|
||||
try
|
||||
{
|
||||
var routingCode = await Context.Queryable<ProcessRouting>()
|
||||
// 在方法内创建上下文,并使用using确保自动释放
|
||||
using var context = DbScoped.SugarScope.CopyNew();
|
||||
if (context == null)
|
||||
throw new InvalidOperationException("无法创建数据库上下文,请检查SqlSugar配置");
|
||||
var routingCode = string.Empty;
|
||||
try
|
||||
{
|
||||
routingCode = await context.Queryable<ProcessRouting>()
|
||||
.LeftJoin<ProcessOperation>((r, o) => r.RoutingCode == o.FkRoutingCode)
|
||||
.Where((r, o) => r.FkProductMaterialCode == strSN && r.Status == 1)
|
||||
.Select((r, o) => o.FkRoutingCode)
|
||||
.Select((r, o) => o.FkRoutingCode)
|
||||
.FirstAsync(); // 直接取第一条,避免ToList+First的双重开销
|
||||
|
||||
// 4.1 工艺路线校验(合并判断,减少分支)
|
||||
if (string.IsNullOrWhiteSpace(routingCode))
|
||||
{
|
||||
Console.WriteLine($"[{now:HH:mm:ss}] {plcName} - {strSN} 工艺路线无效,跳过记录");
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// 5. 返工状态判断(无分配判断,直接赋值)
|
||||
@ -5510,7 +5594,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
};
|
||||
|
||||
// 7. 插入数据库(批量插入优化,减少IO交互)
|
||||
var insertCount = await Context.Insertable(askOutStation).ExecuteCommandAsync();
|
||||
var insertCount = await context.Insertable(askOutStation).ExecuteCommandAsync();
|
||||
|
||||
}
|
||||
catch (ArgumentNullException ex)
|
||||
|
||||
@ -23,7 +23,7 @@ namespace RIZO.Service.PLCBackground.Stations.Into
|
||||
private static Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
private PlcConntectHepler _plcService;
|
||||
private readonly TimeSpan _pollingInterval = TimeSpan.FromSeconds(5);
|
||||
private readonly string _ipAddress = "192.168.11.56";
|
||||
private readonly string _ipAddress = "192.168.1.111";
|
||||
private readonly CpuType _cpuType = CpuType.S71500;
|
||||
private string WorkstationCode;
|
||||
private readonly SqlSugarClient Context;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user