diff --git a/RIZO.Admin.WebApi/PLC/Model/Dto/PlcProductionDataDto.cs b/RIZO.Admin.WebApi/PLC/Model/Dto/PlcProductionDataDto.cs
index f7cdb9d..74a975b 100644
--- a/RIZO.Admin.WebApi/PLC/Model/Dto/PlcProductionDataDto.cs
+++ b/RIZO.Admin.WebApi/PLC/Model/Dto/PlcProductionDataDto.cs
@@ -156,7 +156,15 @@ namespace RIZO.Admin.WebApi.PLC.Model.Dto
public string? ChipSN { get; set; }
-
+ public string? PinPressure1 { get; set; }
+ public string? PinStroke1 { get; set; }
+ public string? PinPressure2 { get; set; }
+ public string? PinStroke2 { get; set; }
+ public string? PressHoldTime { get; set; }
+ public string? TrayBarcode { get; set; }
+ public string? ActualOutQty { get; set; }
+ public string? QualifiedQty { get; set; }
+ public string? FailedQty { get; set; }
[ExcelColumn(Name = "运行状态:1=空闲,2=运行中,3=故障;")]
public string? RunstatusLabel { get; set; }
diff --git a/RIZO.Admin.WebApi/PLC/Model/PlcProductionData.cs b/RIZO.Admin.WebApi/PLC/Model/PlcProductionData.cs
index 6e84fc7..c34d50a 100644
--- a/RIZO.Admin.WebApi/PLC/Model/PlcProductionData.cs
+++ b/RIZO.Admin.WebApi/PLC/Model/PlcProductionData.cs
@@ -470,5 +470,59 @@ namespace RIZO.Admin.WebApi.PLC.Model
///
[SugarColumn(ColumnName = "Product4Result")]
public string Product4Result { get; set; }
+
+ ///
+ /// 1# 销压力
+ ///
+ [SugarColumn(ColumnName = "PinPressure1")]
+ public string PinPressure1 { get; set; }
+
+ ///
+ /// 1# 销行程
+ ///
+ [SugarColumn(ColumnName = "PinStroke1")]
+ public string PinStroke1 { get; set; }
+
+ ///
+ /// 2# 销压力
+ ///
+ [SugarColumn(ColumnName = "PinPressure2")]
+ public string PinPressure2 { get; set; }
+
+ ///
+ /// 2# 销行程
+ ///
+ [SugarColumn(ColumnName = "PinStroke2")]
+ public string PinStroke2 { get; set; }
+
+ ///
+ /// 保压时间
+ ///
+ [SugarColumn(ColumnName = "PressHoldTime")]
+ public string PressHoldTime { get; set; }
+
+ ///
+ /// 波峰焊托盘条码
+ ///
+ [SugarColumn(ColumnName = "trayBarcode")]
+ public string TrayBarcode { get; set; }
+
+ ///
+ /// 实际产量
+ ///
+ [SugarColumn(ColumnName = "actualOutQty")]
+ public string ActualOutQty { get; set; }
+
+ ///
+ /// 合格产量
+ ///
+ [SugarColumn(ColumnName = "qualifiedQty")]
+ public string QualifiedQty { get; set; }
+
+ ///
+ /// 失败产量
+ ///
+ [SugarColumn(ColumnName = "failedQty")]
+ public string FailedQty { get; set; }
}
}
\ No newline at end of file
diff --git a/RIZO.Admin.WebApi/PLC/Service/PlcHostedService.cs b/RIZO.Admin.WebApi/PLC/Service/PlcHostedService.cs
index a4953d2..602ee1d 100644
--- a/RIZO.Admin.WebApi/PLC/Service/PlcHostedService.cs
+++ b/RIZO.Admin.WebApi/PLC/Service/PlcHostedService.cs
@@ -426,7 +426,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
}
else
{
- _logger.LogWarning($"[{config.PlcName}] 生产数据读取失败 | IP:{config.Ip} | 原因:{message}");
// 读取失败更新状态
status.FailCount++;
status.Level = status.FailCount <= 1 ? ConnectionLevel.Weak : ConnectionLevel.Disconnected;
@@ -455,7 +454,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
await Task.WhenAll(tasks);
// 输出本轮轮询统计
- _logger.LogInformation($"PLC轮询完成 | 成功:{successCount} | 失败:{failCount} | 跳过:{skipCount} | 有数据:{activeCount}");
+ //_logger.LogInformation($"PLC轮询完成 | 成功:{successCount} | 失败:{failCount} | 跳过:{skipCount} | 有数据:{activeCount}");
}
///
diff --git a/RIZO.Admin.WebApi/PLC/Service/PlcService.cs b/RIZO.Admin.WebApi/PLC/Service/PlcService.cs
index 553575c..c7262c2 100644
--- a/RIZO.Admin.WebApi/PLC/Service/PlcService.cs
+++ b/RIZO.Admin.WebApi/PLC/Service/PlcService.cs
@@ -50,15 +50,15 @@ namespace RIZO.Admin.WebApi.PLC.Service
//MES返回PLC请求映射
private readonly Dictionary _mesIntReturnMap = new()
{
- { "设备使能", "DB1101.DBW0" }, // Int
- { "工位开始查询结果", "DB1101.DBW2000" }, // Int
- { "保存结果", "DB1101.DBW2002" }, // Int
+ { "设备使能", "DB1317.DBW0" }, // Int
+ { "工位开始查询结果", "DB1317.DBW2000" }, // Int
+ { "保存结果", "DB1317.DBW2002" }, // Int
};
private readonly Dictionary _mesStringReturnMap = new()
{
- { "产品型号", ("DB1101.DBB1016", 14) }, // String[14]
- { "订单下发", ("DB1101.DBB1032", 50) }, // String[50]
+ { "产品型号", ("DB1317.DBB1016", 14) }, // String[14]
+ { "订单下发", ("DB1317.DBB1032", 50) }, // String[50]
};
// OP020-2 专属地址映射(合盖工位,DB1001)
@@ -224,6 +224,128 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ "托盘号", "DB1002.DBW844" } // Int
};
+ // OP057 专属地址映射(压装定位销&激光打标工位,DB1001)
+ private readonly Dictionary _op057StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "SN_1", ("DB1001.DBB2100", 40) }, // String[40]
+ { "SN_2", ("DB1001.DBB2904", 40) } // String[40]
+ };
+
+ private readonly Dictionary _op057IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "1#产品结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求,0=无请求
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2948" }, // Int - 1=OK,2=NG
+ { "1#销结果", "DB1001.DBW2950" }, // Int - 1=OK
+ { "2#销结果", "DB1001.DBW2964" }, // Int - 1=OK
+
+ // 工艺参数(Real)
+ { "1#销压力", "DB1001.DBD2952" }, // Real
+ { "1#销行程", "DB1001.DBD2956" }, // Real
+ { "2#销压力", "DB1001.DBD2966" }, // Real
+ { "2#销行程", "DB1001.DBD2970" }, // Real
+ { "节拍时间", "DB1001.DBD4662" }, // Real
+
+ };
+
+ // OP058 专属地址映射(压装定位销&激光打标工位,DB1004)
+ private readonly Dictionary _op058StringMap = new()
+ {
+ { "产品型号", ("DB1004.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1004.DBB1054", 48) }, // String[48]
+ { "SN_1", ("DB1004.DBB2234", 40) } // String[40] - 条码(查询、上传)
+ };
+
+ private readonly Dictionary _op058IntMap = new()
+ {
+ // 产量数据
+ { "实际产量", "DB1004.DBD1104" }, // DInt
+ { "合格数量", "DB1004.DBD1108" }, // DInt
+ { "失败数量", "DB1004.DBD1112" }, // DInt
+
+ // 产品结果
+ { "产品总结果", "DB1004.DBW2278" }, // Int - 1=OK,2=NG
+ { "结果", "DB1004.DBW2280" }, // Int - 1=OK
+
+ // 工艺参数(Real)
+ { "压力", "DB1004.DBD2282" }, // Real
+ { "行程", "DB1004.DBD2286" }, // Real
+ { "节拍时间", "DB1004.DBD2310" }, // Real
+ };
+
+ // OP060 专属地址映射(高低压接头拧紧工位,DB1001)
+ private readonly Dictionary _op060StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "SN_1", ("DB1001.DBB2100", 40) }, // String[40] - 条码查询
+ { "SN_2", ("DB1001.DBB2274", 40) } // String[40] - 结果上传条码
+ };
+
+ private readonly Dictionary _op060IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "1#产品结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求,0=无请求
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2318" }, // Int - 1=OK,2=NG
+ { "1#螺丝结果", "DB1001.DBW2320" }, // Int
+ { "2#螺丝结果", "DB1001.DBW2338" }, // Int
+ { "3#螺丝结果", "DB1001.DBW2356" }, // Int
+ { "4#螺丝结果", "DB1001.DBW2374" }, // Int
+
+ // 工艺参数(Real)
+ { "1#螺丝扭矩", "DB1001.DBD2322" }, // Real
+ { "1#螺丝深度", "DB1001.DBD2326" }, // Real
+ { "1#螺丝角度", "DB1001.DBD2330" }, // Real
+ { "1#螺丝时间", "DB1001.DBD2334" }, // Real
+ { "2#螺丝扭矩", "DB1001.DBD2340" }, // Real
+ { "2#螺丝深度", "DB1001.DBD2344" }, // Real
+ { "2#螺丝角度", "DB1001.DBD2348" }, // Real
+ { "2#螺丝时间", "DB1001.DBD2352" }, // Real
+ { "3#螺丝扭矩", "DB1001.DBD2358" }, // Real
+ { "3#螺丝深度", "DB1001.DBD2362" }, // Real
+ { "3#螺丝角度", "DB1001.DBD2366" }, // Real
+ { "3#螺丝时间", "DB1001.DBD2370" }, // Real
+ { "4#螺丝扭矩", "DB1001.DBD2376" }, // Real
+ { "4#螺丝深度", "DB1001.DBD2380" }, // Real
+ { "4#螺丝角度", "DB1001.DBD2384" }, // Real
+ { "4#螺丝时间", "DB1001.DBD2388" }, // Real
+ { "节拍时间", "DB1001.DBD3030" }, // Real
+ };
+
// OP070-1 专属地址映射 (点散热胶GF1500工位) OP070-2 点散热胶TC4060 OP070-3 点散热胶GF3500
private readonly Dictionary _op070_1StringMap = new()
{
@@ -285,72 +407,72 @@ namespace RIZO.Admin.WebApi.PLC.Service
// OP080-1 专属地址映射 PCBA组装&拧紧
private readonly Dictionary _op080_1StringMap = new()
{
- //{ "报警信息", ("DB1016.DBB58", 48) }, // Array[1..48] of Byte
- { "订单名称", ("DB1016.DBB1000", 48) }, // String[48]
- { "产品名称", ("DB1016.DBB1054", 48) }, // String[48]
- { "合装位机壳_SN", ("DB1016.DBB2100", 28) }, // String[28]
- { "合装位PCB_SN", ("DB1016.DBB2130", 28) }, // String[28]
- { "拧紧位机壳_SN", ("DB1016.DBB2904", 28) }, // String[28]
- { "拧紧位PCB_SN", ("DB1016.DBB3092", 28) }, // String[28]
+ //{ "报警信息", ("DB1017.DBB58", 48) }, // Array[1..48] of Byte
+ { "订单名称", ("DB1017.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1017.DBB1054", 48) }, // String[48]
+ { "合装位机壳_SN", ("DB1017.DBB2100", 28) }, // String[28]
+ { "合装位PCB_SN", ("DB1017.DBB2130", 28) }, // String[28]
+ { "拧紧位机壳_SN", ("DB1017.DBB2904", 28) }, // String[28]
+ { "拧紧位PCB_SN", ("DB1017.DBB3092", 28) }, // String[28]
};
private readonly Dictionary _op080_1IntMap = new()
{
- { "运行状态", "DB1016.DBW0" }, // Int
- { "设备模式", "DB1016.DBW2" }, // Int
- { "设备在线状态", "DB1016.DBW4" }, // Int
- { "ByPass", "DB1016.DBW6" }, // Int
- { "生产模式", "DB1016.DBW8" }, // Int
- { "实际产量", "DB1016.DBD1104" }, // DInt
- { "合格数量", "DB1016.DBD1108" }, // DInt
- { "失败数量", "DB1016.DBD1112" }, // DInt
- { "合装工位查询请求", "DB1016.DBW2000" }, // Int
- { "合装结果保存请求", "DB1016.DBW2004" }, // Int
- { "拧紧结果保存请求", "DB1016.DBW2006" }, // Int
- { "合装位托盘号", "DB1016.DBW2100" }, // Int
- { "拧紧位托盘号", "DB1016.DBW3152" }, // Int
+ { "运行状态", "DB1017.DBW0" }, // Int
+ { "设备模式", "DB1017.DBW2" }, // Int
+ { "设备在线状态", "DB1017.DBW4" }, // Int
+ { "ByPass", "DB1017.DBW6" }, // Int
+ { "生产模式", "DB1017.DBW8" }, // Int
+ { "实际产量", "DB1017.DBD1104" }, // DInt
+ { "合格数量", "DB1017.DBD1108" }, // DInt
+ { "失败数量", "DB1017.DBD1112" }, // DInt
+ { "合装工位查询请求", "DB1017.DBW2000" }, // Int
+ { "合装结果保存请求", "DB1017.DBW2004" }, // Int
+ { "拧紧结果保存请求", "DB1017.DBW2006" }, // Int
+ { "合装位托盘号", "DB1017.DBW2100" }, // Int
+ { "拧紧位托盘号", "DB1017.DBW3152" }, // Int
// 2号螺钉
- { "2号螺钉_结果", "DB1016.DBW3164" }, // Int
- { "2号螺钉_扭矩", "DB1016.DBD3166" }, // Real
- { "2号螺钉_深度", "DB1016.DBD3170" }, // Real
- { "2号螺钉_角度", "DB1016.DBD3174" }, // Real
- { "2号螺钉_拧紧时间", "DB1016.DBD3178" }, // Real
+ { "2号螺钉_结果", "DB1017.DBW3164" }, // Int
+ { "2号螺钉_扭矩", "DB1017.DBD3166" }, // Real
+ { "2号螺钉_深度", "DB1017.DBD3170" }, // Real
+ { "2号螺钉_角度", "DB1017.DBD3174" }, // Real
+ { "2号螺钉_拧紧时间", "DB1017.DBD3178" }, // Real
// 3号螺钉
- { "3号螺钉_结果", "DB1016.DBW3182" }, // Int
- { "3号螺钉_扭矩", "DB1016.DBD3184" }, // Real
- { "3号螺钉_深度", "DB1016.DBD3188" }, // Real
- { "3号螺钉_角度", "DB1016.DBD3192" }, // Real
- { "3号螺钉_拧紧时间", "DB1016.DBD3196" }, // Real
+ { "3号螺钉_结果", "DB1017.DBW3182" }, // Int
+ { "3号螺钉_扭矩", "DB1017.DBD3184" }, // Real
+ { "3号螺钉_深度", "DB1017.DBD3188" }, // Real
+ { "3号螺钉_角度", "DB1017.DBD3192" }, // Real
+ { "3号螺钉_拧紧时间", "DB1017.DBD3196" }, // Real
// 4号螺钉
- { "4号螺钉_结果", "DB1016.DBW3200" }, // Int
- { "4号螺钉_扭矩", "DB1016.DBD3202" }, // Real
- { "4号螺钉_深度", "DB1016.DBD3206" }, // Real
- { "4号螺钉_角度", "DB1016.DBD3210" }, // Real
- { "4号螺钉_拧紧时间", "DB1016.DBD3214" }, // Real
+ { "4号螺钉_结果", "DB1017.DBW3200" }, // Int
+ { "4号螺钉_扭矩", "DB1017.DBD3202" }, // Real
+ { "4号螺钉_深度", "DB1017.DBD3206" }, // Real
+ { "4号螺钉_角度", "DB1017.DBD3210" }, // Real
+ { "4号螺钉_拧紧时间", "DB1017.DBD3214" }, // Real
// 1号螺钉
- { "1号螺钉_结果", "DB1016.DBW3218" }, // Int
- { "1号螺钉_扭矩", "DB1016.DBD3220" }, // Real
- { "1号螺钉_深度", "DB1016.DBD3224" }, // Real
- { "1号螺钉_角度", "DB1016.DBD3228" }, // Real
- { "1号螺钉_拧紧时间", "DB1016.DBD3232" }, // Real
+ { "1号螺钉_结果", "DB1017.DBW3218" }, // Int
+ { "1号螺钉_扭矩", "DB1017.DBD3220" }, // Real
+ { "1号螺钉_深度", "DB1017.DBD3224" }, // Real
+ { "1号螺钉_角度", "DB1017.DBD3228" }, // Real
+ { "1号螺钉_拧紧时间", "DB1017.DBD3232" }, // Real
// 5号螺钉
- { "5号螺钉_结果", "DB1016.DBW3236" }, // Int
- { "5号螺钉_扭矩", "DB1016.DBD3238" }, // Real
- { "5号螺钉_深度", "DB1016.DBD3242" }, // Real
- { "5号螺钉_角度", "DB1016.DBD3246" }, // Real
- { "5号螺钉_拧紧时间", "DB1016.DBD3250" }, // Real
+ { "5号螺钉_结果", "DB1017.DBW3236" }, // Int
+ { "5号螺钉_扭矩", "DB1017.DBD3238" }, // Real
+ { "5号螺钉_深度", "DB1017.DBD3242" }, // Real
+ { "5号螺钉_角度", "DB1017.DBD3246" }, // Real
+ { "5号螺钉_拧紧时间", "DB1017.DBD3250" }, // Real
// 6号螺钉
- { "6号螺钉_结果", "DB1016.DBW3254" }, // Int
- { "6号螺钉_扭矩", "DB1016.DBD3256" }, // Real
- { "6号螺钉_深度", "DB1016.DBD3260" }, // Real
- { "6号螺钉_角度", "DB1016.DBD3264" }, // Real
- { "6号螺钉_拧紧时间", "DB1016.DBD3268" }, // Real
+ { "6号螺钉_结果", "DB1017.DBW3254" }, // Int
+ { "6号螺钉_扭矩", "DB1017.DBD3256" }, // Real
+ { "6号螺钉_深度", "DB1017.DBD3260" }, // Real
+ { "6号螺钉_角度", "DB1017.DBD3264" }, // Real
+ { "6号螺钉_拧紧时间", "DB1017.DBD3268" }, // Real
// 7号螺钉
- { "7号螺钉_结果", "DB1016.DBW3272" }, // Int
- { "7号螺钉_扭矩", "DB1016.DBD3274" }, // Real
- { "7号螺钉_深度", "DB1016.DBD3278" }, // Real
- { "7号螺钉_角度", "DB1016.DBD3282" }, // Real
- { "7号螺钉_拧紧时间", "DB1016.DBD3286" }, // Real
+ { "7号螺钉_结果", "DB1017.DBW3272" }, // Int
+ { "7号螺钉_扭矩", "DB1017.DBD3274" }, // Real
+ { "7号螺钉_深度", "DB1017.DBD3278" }, // Real
+ { "7号螺钉_角度", "DB1017.DBD3282" }, // Real
+ { "7号螺钉_拧紧时间", "DB1017.DBD3286" }, // Real
};
// OP080-2 专属地址映射(PCBA拧紧工位,DB1001)
@@ -371,9 +493,9 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ "ByPass", "DB1001.DBW6" }, // Int - 1=ByPass,0=正常模式
{ "生产模式", "DB1001.DBW8" }, // Int - 1=点检,2=返工,4=样件,5=正常
- //{ "实际产量", "DB1001.DBD1104" }, // DInt
- //{ "合格数量", "DB1001.DBD1108" }, // DInt
- //{ "失败数量", "DB1001.DBD1112" }, // DInt
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
// 请求信号
{ "查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
@@ -436,6 +558,541 @@ namespace RIZO.Admin.WebApi.PLC.Service
{ "节拍时间", "DB1001.DBD3004" }, // Real
};
+
+ // OP080-3 专属地址映射(PWM压装&CUP上料&拧紧工位,DB1001)
+ private readonly Dictionary _op080_3StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "SN_1", ("DB1001.DBB2100", 40) }, // String[40] - 条码查询
+ { "SN_2", ("DB1001.DBB2200", 40) } // String[40] - 结果上传条码
+ };
+
+ private readonly Dictionary _op080_3IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "保存请求", "DB1001.DBW2002" }, // Int - 1=请求,0=无请求
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2244" }, // Int
+ { "压机结果", "DB1001.DBW2246" }, // Int
+ { "左螺丝枪结果", "DB1001.DBW2264" }, // Int
+ { "右螺丝枪结果", "DB1001.DBW2282" }, // Int
+
+ // 工艺参数(Real)
+ { "压机左压力值", "DB1001.DBD2248" }, // Real
+ { "压机右压力值", "DB1001.DBD2252" }, // Real
+ { "压机行程值", "DB1001.DBD2256" }, // Real
+ { "保压时间", "DB1001.DBD2260" }, // Real
+ { "左螺丝枪扭矩", "DB1001.DBD2266" }, // Real
+ { "左螺丝枪角度", "DB1001.DBD2270" }, // Real
+ { "左螺丝枪深度", "DB1001.DBD2274" }, // Real
+ { "左螺丝枪时间", "DB1001.DBD2278" }, // Real
+ { "右螺丝枪扭矩", "DB1001.DBD2284" }, // Real
+ { "右螺丝枪角度", "DB1001.DBD2288" }, // Real
+ { "右螺丝枪深度", "DB1001.DBD2292" }, // Real
+ { "右螺丝枪时间", "DB1001.DBD2296" }, // Real
+ { "节拍时间", "DB1001.DBD2450" }, // Real
+
+ // 托盘号
+ { "托盘号", "DB1001.DBW2142" } // Int
+ };
+
+ // OP085 专属地址映射(自动上料到波峰焊工位,DB1001)
+ private readonly Dictionary _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]
+ };
+
+ private readonly Dictionary _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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+ { "线体托盘号", "DB1001.DBW2070" }, // Int
+
+ // 工艺参数
+ { "节拍时间", "DB1001.DBD2242" } // Real
+ };
+
+ // OP100 专属地址映射(手动上料壳体&盖板工位,DB1001)
+ private readonly Dictionary _op100StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "产品SN", ("DB1001.DBB2100", 28) } // String[28]
+ };
+
+ private readonly Dictionary _op100IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+
+ // 托盘号
+ { "托盘号", "DB1001.DBW2070" }, // Int
+
+ // 工艺参数
+ { "节拍时间", "DB1001.DBD2958" } // Real
+ };
+ // OP1011 专属地址映射(HV连接器装配工位,DB1001)
+ private readonly Dictionary _op1011StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2100", 40) }, // String[40]
+ { "上传结果SN", ("DB1001.DBB2364", 40) } // String[40]
+ };
+
+ private readonly Dictionary _op1011IntMap = 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=正常
+ { "螺钉枪程序号", "DB1001.DBW998" }, // Int - 给MES提供螺钉枪程序号控制切换
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+ { "请求设备MES传送螺丝", "DB1001.DBW2004" }, // Int
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2364" }, // Int
+ { "1#结果", "DB1001.DBW2464" }, // Int - 0=无结果,1=OK,2=NG
+ { "2#结果", "DB1001.DBW2466" }, // Int - 0=无结果,1=OK,2=NG
+ { "3#结果", "DB1001.DBW2468" }, // Int - 0=无结果,1=OK,2=NG
+ { "4#结果", "DB1001.DBW2470" }, // Int - 0=无结果,1=OK,2=NG
+
+ // 工艺参数(Real)
+ { "1#扭矩", "DB1001.DBD2384" }, // Real
+ { "2#扭矩", "DB1001.DBD2388" }, // Real
+ { "3#扭矩", "DB1001.DBD2392" }, // Real
+ { "4#扭矩", "DB1001.DBD2396" }, // Real
+ { "1#转角", "DB1001.DBD2424" }, // Real
+ { "2#转角", "DB1001.DBD2428" }, // Real
+ { "3#转角", "DB1001.DBD2432" }, // Real
+ { "4#转角", "DB1001.DBD2436" }, // Real
+ { "1#深度", "DB1001.DBD2484" }, // Real
+ { "2#深度", "DB1001.DBD2488" }, // Real
+ { "3#深度", "DB1001.DBD2492" }, // Real
+ { "4#深度", "DB1001.DBD2496" }, // Real
+ { "节拍时间", "DB1001.DBD2690" } // Real
+ };
+ // OP1012 专属地址映射(Ring terminal装配工位,DB1001)
+ private readonly Dictionary _op1012StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2100", 40) }, // String[40]
+ { "上传SN", ("DB1001.DBB2320", 40) } // String[40]
+ };
+
+ private readonly Dictionary _op1012IntMap = 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=正常
+ { "螺钉枪程序号", "DB1001.DBW998" }, // Int
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+ { "请求传送打螺丝结果", "DB1001.DBW2001" }, // Int
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2364" }, // Int - 1=OK,2=NG
+ { "1#结果", "DB1001.DBW2464" }, // Int - 1=OK,2=NG
+ { "2#结果", "DB1001.DBW2466" }, // Int - 1=OK,2=NG
+
+ // 工艺参数(Real)
+ { "1#扭矩", "DB1001.DBD2384" }, // Real
+ { "2#扭矩", "DB1001.DBD2388" }, // Real
+ { "1#转角", "DB1001.DBD2424" }, // Real
+ { "2#转角", "DB1001.DBD2428" }, // Real
+ { "1#深度", "DB1001.DBD2484" }, // Real
+ { "2#深度", "DB1001.DBD2488" }, // Real
+ { "节拍时间", "DB1001.DBD2690" } // Real
+ };
+
+ // OP102 专属地址映射(等离子处理工位,DB1001)
+ private readonly Dictionary _op102StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2100", 28) }, // String[28]
+ { "上传结果SN", ("DB1001.DBB2134", 28) } // String[28]
+ };
+
+ private readonly Dictionary _op102IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "产品保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+
+ // 托盘与站位
+ { "托盘号", "DB1001.DBW2104" }, // Int
+ { "站位结果", "DB1001.DBW2166" }, // Int
+
+ // 工艺参数
+ { "节拍时间", "DB1001.DBD2168" } // Real
+ };
+
+ // OP110-1 专属地址映射(点胶封胶Q3-3636工位,DB1001)
+ private readonly Dictionary _op110_1StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2100", 28) }, // String[28]
+ { "上传结果SN", ("DB1001.DBB2134", 28) } // String[28]
+ };
+
+ private readonly Dictionary _op110_1IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "产品保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+
+ // 结果与托盘
+ { "托盘号", "DB1001.DBW2004" }, // Int
+ { "相机结果", "DB1001.DBW2164" }, // Int
+ { "站位结果", "DB1001.DBW2166" }, // Int
+
+ // 工艺参数
+ { "节拍时间", "DB1001.DBD2168" } // Real
+ };
+
+ // OP110-2 专属地址映射(盖板组装&拧紧工位,DB1001)
+ private readonly Dictionary _op110_2StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "合装工位查询SN", ("DB1001.DBB2100", 28) }, // String[28]
+ { "拧紧工位上传结果SN", ("DB1001.DBB2616", 28) } // String[28]
+ };
+
+ private readonly Dictionary _op110_2IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "产品保存请求", "DB1001.DBW2006" }, // Int - 1=请求开始,0=无请求
+
+ // 合装与托盘
+ { "合装工位托盘号", "DB1001.DBW2130" }, // Int
+ { "托盘号", "DB1001.DBW2646" }, // Int
+ { "产品总结果", "DB1001.DBW2648" }, // Int
+
+ // 螺丝结果(3#-7#)
+ { "3#螺丝结果", "DB1001.DBW2662" }, // Int
+ { "5#螺丝结果", "DB1001.DBW2680" }, // Int
+ { "6#螺丝结果", "DB1001.DBW2698" }, // Int
+ { "1#螺丝结果", "DB1001.DBW2716" }, // Int
+ { "2#螺丝结果", "DB1001.DBW2734" }, // Int
+ { "4#螺丝结果", "DB1001.DBW2752" }, // Int
+ { "7#螺丝结果", "DB1001.DBW2770" }, // Int
+
+ // 螺丝工艺参数(Real)
+ { "3#扭矩", "DB1001.DBD2664" }, // Real
+ { "3#深度", "DB1001.DBD2668" }, // Real
+ { "3#角度", "DB1001.DBD2672" }, // Real
+ { "3#拧紧时间", "DB1001.DBD2676" }, // Real
+ { "5#扭矩", "DB1001.DBD2682" }, // Real
+ { "5#深度", "DB1001.DBD2686" }, // Real
+ { "5#角度", "DB1001.DBD2690" }, // Real
+ { "5#拧紧时间", "DB1001.DBD2694" }, // Real
+ { "6#扭矩", "DB1001.DBD2700" }, // Real
+ { "6#深度", "DB1001.DBD2704" }, // Real
+ { "6#角度", "DB1001.DBD2708" }, // Real
+ { "6#拧紧时间", "DB1001.DBD2712" }, // Real
+ { "1#扭矩", "DB1001.DBD2718" }, // Real
+ { "1#深度", "DB1001.DBD2722" }, // Real
+ { "1#角度", "DB1001.DBD2726" }, // Real
+ { "1#拧紧时间", "DB1001.DBD2730" }, // Real
+ { "2#扭矩", "DB1001.DBD2736" }, // Real
+ { "2#深度", "DB1001.DBD2740" }, // Real
+ { "2#角度", "DB1001.DBD2744" }, // Real
+ { "2#拧紧时间", "DB1001.DBD2748" }, // Real
+ { "4#扭矩", "DB1001.DBD2754" }, // Real
+ { "4#深度", "DB1001.DBD2758" }, // Real
+ { "4#角度", "DB1001.DBD2762" }, // Real
+ { "4#拧紧时间", "DB1001.DBD2766" }, // Real
+ { "7#扭矩", "DB1001.DBD2772" }, // Real
+ { "7#深度", "DB1001.DBD2776" }, // Real
+ { "7#角度", "DB1001.DBD2780" }, // Real
+ { "7#拧紧时间", "DB1001.DBD2784" }, // Real
+ { "节拍时间", "DB1001.DBD3518" } // Real
+ };
+
+ // OP110-3 专属地址映射(盖板拧紧工位,DB1001)
+ private readonly Dictionary _op110_3StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2100", 28) }, // String[28]
+ { "保存SN", ("DB1001.DBB2258", 28) } // String[28]
+ };
+
+ private readonly Dictionary _op110_3IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位开始查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "1#产品结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+
+ // 产品结果
+ { "产品总结果", "DB1001.DBW2288" }, // Int
+ { "1#螺丝结果", "DB1001.DBW2290" }, // Int
+ { "2#螺丝结果", "DB1001.DBW2308" }, // Int
+ { "3#螺丝结果", "DB1001.DBW2326" }, // Int
+ { "4#螺丝结果", "DB1001.DBW2344" }, // Int
+ { "5#螺丝结果", "DB1001.DBW2362" }, // Int
+ { "6#螺丝结果", "DB1001.DBW2380" }, // Int
+ { "7#螺丝结果", "DB1001.DBW2398" }, // Int
+
+ // 螺丝工艺参数(Real)
+ { "1#扭矩", "DB1001.DBD2292" }, // Real
+ { "1#深度", "DB1001.DBD2296" }, // Real
+ { "1#角度", "DB1001.DBD2300" }, // Real
+ { "1#拧紧时间", "DB1001.DBD2304" }, // Real
+ { "2#扭矩", "DB1001.DBD2310" }, // Real
+ { "2#深度", "DB1001.DBD2314" }, // Real
+ { "2#角度", "DB1001.DBD2318" }, // Real
+ { "2#拧紧时间", "DB1001.DBD2322" }, // Real
+ { "3#扭矩", "DB1001.DBD2328" }, // Real
+ { "3#深度", "DB1001.DBD2332" }, // Real
+ { "3#角度", "DB1001.DBD2336" }, // Real
+ { "3#拧紧时间", "DB1001.DBD2340" }, // Real
+ { "4#扭矩", "DB1001.DBD2346" }, // Real
+ { "4#深度", "DB1001.DBD2350" }, // Real
+ { "4#角度", "DB1001.DBD2354" }, // Real
+ { "4#拧紧时间", "DB1001.DBD2358" }, // Real
+ { "5#扭矩", "DB1001.DBD2364" }, // Real
+ { "5#深度", "DB1001.DBD2368" }, // Real
+ { "5#角度", "DB1001.DBD2372" }, // Real
+ { "5#拧紧时间", "DB1001.DBD2376" }, // Real
+ { "6#扭矩", "DB1001.DBD2382" }, // Real
+ { "6#深度", "DB1001.DBD2386" }, // Real
+ { "6#角度", "DB1001.DBD2390" }, // Real
+ { "6#拧紧时间", "DB1001.DBD2394" }, // Real
+ { "7#扭矩", "DB1001.DBD2400" }, // Real
+ { "7#深度", "DB1001.DBD2404" }, // Real
+ { "7#角度", "DB1001.DBD2408" }, // Real
+ { "7#拧紧时间", "DB1001.DBD2412" }, // Real
+ { "节拍时间", "DB1001.DBD3036" }, // Real
+
+ // 托盘号
+ { "托盘号", "DB1001.DBW2072" } // Int
+ };
+
+ // OP115 专属地址映射(自动上下料到固化炉工位,DB1001)
+ private readonly Dictionary _op115StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) } // String[48]
+ };
+
+ private readonly Dictionary _op115IntMap = 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=正常
+ };
+
+ // OP140 专属地址映射(气密性测试工位,DB1001)
+ private readonly Dictionary _op140StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2146", 40) } // String[40]
+ };
+
+ private readonly Dictionary _op140IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+
+ // 测试结果
+ { "结果SN", "DB1001.DBW2260" }, // Int
+ { "Socket", "DB1001.DBW2302" }, // Int - 1:工位1;2:工位2
+ { "产品结果", "DB1001.DBW2304" }, // Int
+ { "托盘号", "DB1001.DBW2318" }, // Int
+
+ // 工艺参数(Real)
+ { "压力值", "DB1001.DBD2306" }, // Real
+ { "泄露值", "DB1001.DBD2310" }, // Real
+ { "节拍时间", "DB1001.DBD2314" } // Real
+ };
+
+ // OP165 专属地址映射(自动贴标工位,DB1001)
+ private readonly Dictionary _op165StringMap = new()
+ {
+ { "报警信息", ("DB1001.DBB58", 48) }, // Array[1..48] of Byte
+ { "产品型号", ("DB1001.DBB1000", 48) }, // String[48]
+ { "产品名称", ("DB1001.DBB1054", 48) }, // String[48]
+ { "查询SN", ("DB1001.DBB2060", 40) }, // String[40]
+ { "结果SN", ("DB1001.DBB2170", 40) }, // String[40]
+ { "二维码内容", ("DB1001.DBB2226", 28) }, // String[28]
+ { "下料工位条码", ("DB1001.DBB2876", 40) } // String[40]
+ };
+
+ private readonly Dictionary _op165IntMap = 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=正常
+
+ // 产量数据
+ { "实际产量", "DB1001.DBD1104" }, // DInt
+ { "合格数量", "DB1001.DBD1108" }, // DInt
+ { "失败数量", "DB1001.DBD1112" }, // DInt
+
+ // 操作请求
+ { "工位查询请求", "DB1001.DBW2000" }, // Int - 1=请求开始,0=无请求
+ { "结果保存请求", "DB1001.DBW2002" }, // Int - 1=请求开始,0=无请求
+ { "下料工位条码上传", "DB1001.DBW2874" }, // Int
+
+ // 检测结果
+ { "产品总结果", "DB1001.DBW2214" }, // Int
+ { "轴承检测结果", "DB1001.DBW2216" }, // Int
+ { "贴标拍照结果", "DB1001.DBW2218" }, // Int
+ { "托盘号", "DB1001.DBW2220" }, // Int
+
+ // 工艺参数
+ { "节拍时间", "DB1001.DBD2222" } // Real
+ };
#endregion
///
/// 构造函数(依赖注入获取PLC配置)
@@ -465,7 +1122,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
/// PLC生产数据读取核心方法(优化版)
///
/// 成功状态/生产数据/提示消息
- async Task<(bool Success, PlcProductionData Data, string Message)> ReadProductionDataAsync(
+ public async Task<(bool Success, PlcProductionData Data, string Message)> ReadProductionDataAsync(
string ip,
string plcName,
short rack,
@@ -582,12 +1239,21 @@ namespace RIZO.Admin.WebApi.PLC.Service
case "OP050":
iSaveRequest = await ReadPlcIntAsync(plc, _op050IntMap["上传请求"]).ConfigureAwait(false);
break;
- case "OP050_1":
+ case "OP050-1":
iSaveRequest = 1;
break;
- case " ":
+ case "OP051扫码":
iSaveRequest = await ReadPlcIntAsync(plc, _op051ScanIntMap["上传结果请求"]).ConfigureAwait(false);
break;
+ case "OP057":
+ iSaveRequest = await ReadPlcIntAsync(plc, _op057IntMap["1#产品结果保存请求"]).ConfigureAwait(false);
+ break;
+ case "OP058":
+ iSaveRequest = 1;
+ break;
+ case "OP060":
+ iSaveRequest = await ReadPlcIntAsync(plc, _op060IntMap["1#产品结果保存请求"]).ConfigureAwait(false);
+ break;
case "OP070-1":
case "OP070-2":
case "OP070-3":
@@ -609,6 +1275,15 @@ namespace RIZO.Admin.WebApi.PLC.Service
: $"{strSaveRequest},拧紧结果保存请求";
}
break;
+ case "OP080-2":
+ iSaveRequest = await ReadPlcIntAsync(plc, _op080_2IntMap["保存请求"]).ConfigureAwait(false);
+ break;
+ case "OP080-3":
+ iSaveRequest = await ReadPlcIntAsync(plc, _op080_3IntMap["保存请求"]).ConfigureAwait(false);
+ break;
+ case "OP085":
+ iSaveRequest = await ReadPlcIntAsync(plc, _op085IntMap["保存请求"]).ConfigureAwait(false);
+ break;
}
if (iSaveRequest != 1) return (false, null, string.Empty);
if (iSaveRequest == 1)
@@ -620,11 +1295,27 @@ namespace RIZO.Admin.WebApi.PLC.Service
"OP020-3" => await ReadOP020_3DataAsync(plc, ip, plcName).ConfigureAwait(false),
"OP020-4" => await ReadOP020_4DataAsync(plc, ip, plcName).ConfigureAwait(false),
"OP050" => await ReadOP050DataAsync(plc, ip, plcName).ConfigureAwait(false),
- "OP050_1" => await ReadOP050_1DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP050-1" => await ReadOP050_1DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP051扫码" => await ReadOP051ScanDataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP057" => await ReadOP057DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP058" => await ReadOP058DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP060" => await ReadOP060DataAsync(plc, ip, plcName).ConfigureAwait(false),
"OP070-1" or "OP070-2" or "OP070-3" => await ReadOP070_1DataAsync(plc, ip, plcName).ConfigureAwait(false),
"OP075" => await ReadOP075DataAsync(plc, ip, plcName).ConfigureAwait(false),
"OP080-1" => await ReadOP080_1DataAsync(plc, ip, plcName, strSaveRequest).ConfigureAwait(false),
"OP080-2" => await ReadOP080_2DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP080-3" => await ReadOP080_3DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP085" => await ReadOP085DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP100" => await ReadOP100DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP1011" => await ReadOP1011DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP1012" => await ReadOP1012DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP102" => await ReadOP102DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP110-1" => await ReadOP110_1DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP110-2" => await ReadOP110_2DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP110-3" => await ReadOP110_3DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP115" => await ReadOP115DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP140" => await ReadOP140DataAsync(plc, ip, plcName).ConfigureAwait(false),
+ "OP165" => await ReadOP165DataAsync(plc, ip, plcName).ConfigureAwait(false),
_ => prodData
};
@@ -757,6 +1448,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2",
WorkstationCode = workstationCode,
+ WorkstationName = "合盖", // 补充工站名称
ProductModel = productModel,
ProductName = productName,
ProductCode = sn,
@@ -846,7 +1538,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2",
WorkstationCode = workstationCode,
-
+ WorkstationName = "热铆", // 补充工站名称
// 状态字段:直接赋值,无冗余转换
ReworkFlag = reworkFlag,
Automanual = machineModel,
@@ -954,6 +1646,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2",
WorkstationCode = workstationCode,
+ WorkstationName = "pin压合&视觉检查", // 补充工站名称
ProductModel = productModel,
ProductName = productName,
ProductCode = product1SN, // 主产品编码取产品1SN(可根据业务调整)
@@ -1092,6 +1785,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2", // 按实际产线调整,建议后续改为参数
WorkstationCode = workstationCode,
+ WorkstationName = "点白胶DC744", // 补充工站名称
ProductModel = productModel,
ProductName = productName,
ProductCode = product1SN, // 主产品编码取产品1SN
@@ -1108,6 +1802,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
Product2SN = product2SN,
Product3SN = product3SN,
Product4SN = product4SN,
+
+ ActualOutQty = actualOutput.ToString(),
+ QualifiedQty = qualifiedQty.ToString(),
+ FailedQty = failedQty.ToString(),
// 兼容原有SN字段
SN1 = product1SN,
SN2 = product2SN,
@@ -1118,6 +1816,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
}
catch
{
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP050读取异常");
return null;
}
}
@@ -1215,6 +1914,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
PlcIp = ip,
OccurTime = DateTime.Now,
LineCode = "line2", // 按实际产线调整,建议改为参数
+ WorkstationName = "自动下料", // 补充工站名称
WorkstationCode = workstationCode,
ProductModel = productModel,
ProductName = productName,
@@ -1234,9 +1934,516 @@ namespace RIZO.Admin.WebApi.PLC.Service
Remark = $"实际产量:{actualOutput},合格数量:{qualifiedQty},失败数量:{failedQty},节拍时间:{cycleTime:F2}秒"
};
}
- catch
+ catch(Exception ex)
{
// 异常静默处理,返回null避免上层崩溃
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP050_1读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP051扫码工位数据(适配Coating扫码业务,无冗余逻辑)
+ ///
+ /// PLC连接实例
+ /// PLC IP地址
+ /// 工位编码(如OP051)
+ /// PLC生产数据实体
+ public async Task ReadOP051ScanDataAsync(Plc plc, string ip, string workstationCode)
+ {
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip)) throw new ArgumentNullException(nameof(ip), "PLC IP地址不能为空");
+ if (string.IsNullOrWhiteSpace(workstationCode)) throw new ArgumentNullException(nameof(workstationCode), "工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务(按类型分类,最大化并行效率)
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op051ScanStringMap["产品型号"].Addr, _op051ScanStringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op051ScanStringMap["产品名称"].Addr, _op051ScanStringMap["产品名称"].Len) },
+ { "SN_1", ReadPlcStringAsync(plc, _op051ScanStringMap["SN_1"].Addr, _op051ScanStringMap["SN_1"].Len) },
+ { "SN_2", ReadPlcStringAsync(plc, _op051ScanStringMap["SN_2"].Addr, _op051ScanStringMap["SN_2"].Len) },
+ { "SN_3", ReadPlcStringAsync(plc, _op051ScanStringMap["SN_3"].Addr, _op051ScanStringMap["SN_3"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op051ScanIntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op051ScanIntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op051ScanIntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op051ScanIntMap["生产模式"]) },
+ { "查询请求", ReadPlcIntAsync(plc, _op051ScanIntMap["查询请求"]) },
+ { "上传结果请求", ReadPlcIntAsync(plc, _op051ScanIntMap["上传结果请求"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op051ScanIntMap["托盘号"]) }
+ };
+
+ // 2. 并行等待所有任务完成(单次WaitAll,最小化等待时间)
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果(直接取值,空值兜底,减少内存分配)
+ var now = DateTime.Now; // 单次获取时间,减少系统调用
+ var productModel = stringTasks["产品型号"].Result;
+ var productName = stringTasks["产品名称"].Result;
+ var sn1 = stringTasks["SN_1"].Result;
+ var sn2 = stringTasks["SN_2"].Result;
+ var sn3 = stringTasks["SN_3"].Result;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var queryRequest = intTasks["查询请求"].Result;
+ var uploadRequest = intTasks["上传结果请求"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString(); // 转换为字符串,适配实体字段
+
+ // 4. 核心逻辑转换(极简表达式,适配扫码工位业务)
+ var reworkFlag = produceModel == 4 ? "1" : "0"; // 4=返工模式→1,其他→0
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "正常模式",
+ 2 => "清线模式",
+ 4 => "返工模式",
+ 8 => "换型模式",
+ 16 => "预热模式",
+ _ => $"未知模式({produceModel})"
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var queryRequestDesc = queryRequest != 0 ? "有查询请求" : "无查询请求";
+ var uploadRequestDesc = uploadRequest != 0 ? "有上传请求" : "无上传请求";
+ var qualificationFlag = "1"; // 扫码工位默认合格(无检测结果,可根据业务调整)
+
+
+ // 6. 构建并返回实体(适配扫码工位特性,精简字段)
+ return new PlcProductionData
+ {
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2", // 可改为参数传入
+ WorkstationCode = workstationCode,
+ WorkstationName = "Coating扫码", // 补充工站名称
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn2, // 主SN用SN_1
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ TrayNo = trayNo,
+ SN1 = sn1,
+ SN2 = sn2,
+ Product1SN = sn1,
+ Product2SN = sn2,
+ Product3SN = sn3,
+ QualificationFlag = qualificationFlag,
+ CreatedBy = "PLC",
+ CreatedTime = now,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP051扫码工位读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP057数据(压装定位销&激光打标工位,DB1001)
+ ///
+ private async Task ReadOP057DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:PLC连接无效直接返回
+ if (plc == null || !plc.IsConnected)
+ {
+ return null;
+ }
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringReadTasks = new Dictionary>
+ {
+ { "报警信息", ReadPlcStringAsync(plc, _op057StringMap["报警信息"].Addr, _op057StringMap["报警信息"].Len) },
+ { "产品型号", ReadPlcStringAsync(plc, _op057StringMap["产品型号"].Addr, _op057StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op057StringMap["产品名称"].Addr, _op057StringMap["产品名称"].Len) },
+ { "SN_1", ReadPlcStringAsync(plc, _op057StringMap["SN_1"].Addr, _op057StringMap["SN_1"].Len) },
+ { "SN_2", ReadPlcStringAsync(plc, _op057StringMap["SN_2"].Addr, _op057StringMap["SN_2"].Len) }
+ };
+
+ var intReadTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op057IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op057IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op057IntMap["设备在线状态"]) },
+ { "ByPass", ReadPlcIntAsync(plc, _op057IntMap["ByPass"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op057IntMap["生产模式"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op057IntMap["产品总结果"]) },
+ { "1#销结果", ReadPlcIntAsync(plc, _op057IntMap["1#销结果"]) },
+ { "2#销结果", ReadPlcIntAsync(plc, _op057IntMap["2#销结果"]) }
+ };
+
+ var dIntReadTasks = new Dictionary>
+ {
+ { "实际产量", ReadPlcIntAsync(plc, _op057IntMap["实际产量"]) },
+ { "合格数量", ReadPlcIntAsync(plc, _op057IntMap["合格数量"]) },
+ { "失败数量", ReadPlcIntAsync(plc, _op057IntMap["失败数量"]) }
+ };
+
+ var realReadTasks = new Dictionary>
+ {
+ { "1#销压力", ReadPlcRealAsync(plc, _op057IntMap["1#销压力"]) },
+ { "1#销行程", ReadPlcRealAsync(plc, _op057IntMap["1#销行程"]) },
+ { "2#销压力", ReadPlcRealAsync(plc, _op057IntMap["2#销压力"]) },
+ { "2#销行程", ReadPlcRealAsync(plc, _op057IntMap["2#销行程"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op057IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有读取任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringReadTasks.Values);
+ allTasks.AddRange(intReadTasks.Values);
+ allTasks.AddRange(dIntReadTasks.Values);
+ allTasks.AddRange(realReadTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取读取结果
+ string productModel = stringReadTasks["产品型号"].Result ?? string.Empty;
+ string productName = stringReadTasks["产品名称"].Result ?? string.Empty;
+ string sn1 = stringReadTasks["SN_1"].Result ?? string.Empty;
+ string sn2 = stringReadTasks["SN_2"].Result ?? string.Empty;
+
+ int runStatus = intReadTasks["运行状态"].Result;
+ int machineModel = intReadTasks["设备模式"].Result;
+ int onlineStatus = intReadTasks["设备在线状态"].Result;
+ int produceModel = intReadTasks["生产模式"].Result;
+ int productTotalResult = intReadTasks["产品总结果"].Result;
+
+ int pin1Result = intReadTasks["1#销结果"].Result;
+ int pin2Result = intReadTasks["2#销结果"].Result;
+
+ int actualOutput = dIntReadTasks["实际产量"].Result;
+ int qualifiedQty = dIntReadTasks["合格数量"].Result;
+ int failedQty = dIntReadTasks["失败数量"].Result;
+
+ float pin1Pressure = realReadTasks["1#销压力"].Result;
+ float pin1Stroke = realReadTasks["1#销行程"].Result;
+ float pin2Pressure = realReadTasks["2#销压力"].Result;
+ float pin2Stroke = realReadTasks["2#销行程"].Result;
+ float cycleTime = realReadTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ string reworkFlag = produceModel == 2 ? "1" : "0";
+ string produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ string onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ string qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+
+ // 5. 构建实体
+ return new PlcProductionData
+ {
+ PlcIp = ip,
+ OccurTime = DateTime.Now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "压装定位销&激光打标", // 补充工站名称
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ PinPressure1 = pin1Pressure.ToString(),
+ PinStroke1 = pin1Stroke.ToString(),
+ PinPressure2 = pin2Pressure.ToString(),
+ PinStroke2 = pin2Stroke.ToString(),
+ CreatedBy = "PLC",
+ CreatedTime = DateTime.Now,
+ SN1 = sn1,
+ SN2 = sn2,
+ Product1SN = sn1,
+ Product2SN = sn2,
+ Product1Result = pin1Result.ToString(),
+ Product2Result = pin2Result.ToString(),
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP057读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP058数据(压装定位销&激光打标工位)
+ ///
+ public async Task ReadOP058DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op058StringMap["产品型号"].Addr, _op058StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op058StringMap["产品名称"].Addr, _op058StringMap["产品名称"].Len) },
+ { "SN_1", ReadPlcStringAsync(plc, _op058StringMap["SN_1"].Addr, _op058StringMap["SN_1"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "实际产量", ReadPlcIntAsync(plc, _op058IntMap["实际产量"]) },
+ { "合格数量", ReadPlcIntAsync(plc, _op058IntMap["合格数量"]) },
+ { "失败数量", ReadPlcIntAsync(plc, _op058IntMap["失败数量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op058IntMap["产品总结果"]) },
+ { "结果", ReadPlcIntAsync(plc, _op058IntMap["结果"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "压力", ReadPlcRealAsync(plc, _op058IntMap["压力"]) },
+ { "行程", ReadPlcRealAsync(plc, _op058IntMap["行程"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op058IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["SN_1"].Result ?? string.Empty;
+
+ var actualOutput = intTasks["实际产量"].Result;
+ var qualifiedQty = intTasks["合格数量"].Result;
+ var failedQty = intTasks["失败数量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var result = intTasks["结果"].Result;
+
+ var pressure = realTasks["压力"].Result;
+ var stroke = realTasks["行程"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 5. 构建实体
+ return new PlcProductionData
+ {
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "压装定位销&激光打标", // 补充工站名称
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ Product1SN = sn1,
+ Product1Result = result.ToString(),
+ PinPressure1 = pressure.ToString(),
+ PinStroke1 = stroke.ToString(),
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC_System",
+ CreatedTime = now,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP058读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP060数据(高低压接头拧紧工位,DB1001)
+ ///
+ public async Task ReadOP060DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op060StringMap["产品型号"].Addr, _op060StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op060StringMap["产品名称"].Addr, _op060StringMap["产品名称"].Len) },
+ { "SN_1", ReadPlcStringAsync(plc, _op060StringMap["SN_1"].Addr, _op060StringMap["SN_1"].Len) },
+ { "SN_2", ReadPlcStringAsync(plc, _op060StringMap["SN_2"].Addr, _op060StringMap["SN_2"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op060IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op060IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op060IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op060IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op060IntMap["实际产量"]) },
+ { "合格数量", ReadPlcIntAsync(plc, _op060IntMap["合格数量"]) },
+ { "失败数量", ReadPlcIntAsync(plc, _op060IntMap["失败数量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op060IntMap["产品总结果"]) },
+ { "1#螺丝结果", ReadPlcIntAsync(plc, _op060IntMap["1#螺丝结果"]) },
+ { "2#螺丝结果", ReadPlcIntAsync(plc, _op060IntMap["2#螺丝结果"]) },
+ { "3#螺丝结果", ReadPlcIntAsync(plc, _op060IntMap["3#螺丝结果"]) },
+ { "4#螺丝结果", ReadPlcIntAsync(plc, _op060IntMap["4#螺丝结果"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "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#螺丝角度"]) },
+ { "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#螺丝角度"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op060IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["SN_1"].Result ?? string.Empty;
+ var sn2 = stringTasks["SN_2"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var screw1Result = intTasks["1#螺丝结果"].Result;
+ var screw2Result = intTasks["2#螺丝结果"].Result;
+ var screw3Result = intTasks["3#螺丝结果"].Result;
+ var screw4Result = intTasks["4#螺丝结果"].Result;
+
+ var screw1Torque = realTasks["1#螺丝扭矩"].Result;
+ var screw1Depth = realTasks["1#螺丝深度"].Result;
+ var screw1Angle = realTasks["1#螺丝角度"].Result;
+ var screw2Torque = realTasks["2#螺丝扭矩"].Result;
+ var screw2Depth = realTasks["2#螺丝深度"].Result;
+ var screw2Angle = realTasks["2#螺丝角度"].Result;
+ var screw3Torque = realTasks["3#螺丝扭矩"].Result;
+ var screw3Depth = realTasks["3#螺丝深度"].Result;
+ var screw3Angle = realTasks["3#螺丝角度"].Result;
+ var screw4Torque = realTasks["4#螺丝扭矩"].Result;
+ var screw4Depth = realTasks["4#螺丝深度"].Result;
+ var screw4Angle = realTasks["4#螺丝角度"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+
+ // 6. 构建实体
+ // 6. 构建完整实体(覆盖所有螺丝参数字段)
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "高低压接头拧紧工位", // 补充工站名称
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 螺丝1参数(完整赋值)
+ Screw1Result = screw1Result.ToString(),
+ Screw1Torque = screw1Torque.ToString("F2"),
+ Screw1Depth = screw1Depth.ToString("F2"),
+ Screw1Angle = screw1Angle.ToString("F2"),
+ Screw1TightenTime = realTasks["1#螺丝时间"].Result.ToString("F2"),
+
+ // 螺丝2参数(完整赋值)
+ Screw2Result = screw2Result.ToString(),
+ Screw2Torque = screw2Torque.ToString("F2"),
+ Screw2Depth = screw2Depth.ToString("F2"),
+ Screw2Angle = screw2Angle.ToString("F2"),
+ Screw2TightenTime = realTasks["2#螺丝时间"].Result.ToString("F2"),
+
+ // 螺丝3参数(完整赋值)
+ Screw3Result = screw3Result.ToString(),
+ Screw3Torque = screw3Torque.ToString("F2"),
+ Screw3Depth = screw3Depth.ToString("F2"),
+ Screw3Angle = screw3Angle.ToString("F2"),
+ Screw3TightenTime = realTasks["3#螺丝时间"].Result.ToString("F2"),
+
+ // 螺丝4参数(完整赋值)
+ Screw4Result = screw4Result.ToString(),
+ Screw4Torque = screw4Torque.ToString("F2"),
+ Screw4Depth = screw4Depth.ToString("F2"),
+ Screw4Angle = screw4Angle.ToString("F2"),
+ Screw4TightenTime = realTasks["4#螺丝时间"].Result.ToString("F2"),
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP060读取异常:{ex.Message}");
return null;
}
}
@@ -1338,6 +2545,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
PlcIp = ip, // 外层已校验ip非空,无需Trim(减少字符串操作)
OccurTime = DateTime.Now,
LineCode = "line2",
+ WorkstationName = "点散热胶",
WorkstationCode = workstationCode,
ProductModel = productModel,
ProductName = productName,
@@ -1460,6 +2668,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2",
WorkstationCode = workstationCode,
+ WorkstationName = "PWM折弯&装配",
ProductModel = productModel,
ProductName = productName,
ProductCode = sn2,
@@ -1549,6 +2758,14 @@ namespace RIZO.Admin.WebApi.PLC.Service
ReadPlcIntAsync(plc, _op080_1IntMap["7号螺钉_结果"])
};
+ // DInt(双整数)读取任务(复用ReadPlcIntAsync,PLC底层兼容DInt转int)
+ var dIntReadTasks = new Dictionary>
+ {
+ { "实际产量", ReadPlcIntAsync(plc, _op080_1IntMap["实际产量"]) },
+ { "合格数量", ReadPlcIntAsync(plc, _op080_1IntMap["合格数量"]) },
+ { "失败数量", ReadPlcIntAsync(plc, _op080_1IntMap["失败数量"]) }
+ };
+
// 1.3 Real字段任务(28个)- 按螺钉分组,批量存储(减少硬编码)
var realTasks = new List>();
// 预定义螺钉字段前缀(复用数组,减少GC)
@@ -1567,6 +2784,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
allTasks.AddRange(stringTasks); // 字符串任务(Task 继承自 Task)
allTasks.AddRange(intTasks); // Int任务(Task 继承自 Task)
allTasks.AddRange(realTasks); // Real任务(Task 继承自 Task)
+ allTasks.AddRange(dIntReadTasks.Values);
await Task.WhenAll(allTasks).ConfigureAwait(false); // 取消上下文捕获,提升性能
// ========== 阶段3:批量获取结果(索引访问,减少临时变量) ==========
@@ -1596,6 +2814,10 @@ namespace RIZO.Admin.WebApi.PLC.Service
intTasks[13].Result, intTasks[14].Result, intTasks[15].Result, intTasks[16].Result
};
+ int actualOutput = dIntReadTasks["实际产量"].Result;
+ int qualifiedQty = dIntReadTasks["合格数量"].Result;
+ int failedQty = dIntReadTasks["失败数量"].Result;
+
// 3.3 Real结果(按螺钉维度批量读取,索引0-27:7螺钉×4维度)
float[] realResults = realTasks.Select(t => t.Result).ToArray();
// 按螺钉分组提取(复用数组,减少临时变量)
@@ -1631,6 +2853,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2",
WorkstationCode = workstationCode,
+ WorkstationName = "PCBA组装&拧紧",
ProductName = productName,
ProductCode = njPcbsn,
@@ -1657,6 +2880,11 @@ namespace RIZO.Admin.WebApi.PLC.Service
TightenHousingSN = njMachineSN,
TightenPCBSN = njPcbsn,
+
+ ActualOutQty = actualOutput.ToString(),
+ QualifiedQty = qualifiedQty.ToString(),
+ FailedQty = failedQty.ToString(),
+
// 螺钉相关字段(批量赋值,减少重复代码)
// 1号螺钉
Screw1Result = screwResults[0].ToString(),
@@ -1711,7 +2939,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
UpdatedBy = string.Empty,
UpdatedTime = null,
ProductModel = string.Empty,
- WorkstationName = string.Empty,
CameraResult = string.Empty
};
@@ -1878,6 +3105,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
OccurTime = DateTime.Now,
LineCode = "line2", // 按实际产线调整
WorkstationCode = plcName, // 直接使用传入的plcName作为工位编码
+ WorkstationName = "PCBA拧紧",
ProductModel = productModel ?? string.Empty, // OP080-2有产品型号字段
ProductName = productName ?? string.Empty,
ProductCode = sn2 ?? string.Empty, // 结果上传条码作为产品编码
@@ -1954,6 +3182,1637 @@ namespace RIZO.Admin.WebApi.PLC.Service
return null;
}
}
+
+ ///
+ /// 读取OP080-3数据(PWM压装&CUP上料&拧紧工位,DB1001)
+ ///
+ public async Task ReadOP080_3DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op080_3StringMap["产品型号"].Addr, _op080_3StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op080_3StringMap["产品名称"].Addr, _op080_3StringMap["产品名称"].Len) },
+ { "SN_1", ReadPlcStringAsync(plc, _op080_3StringMap["SN_1"].Addr, _op080_3StringMap["SN_1"].Len) },
+ { "SN_2", ReadPlcStringAsync(plc, _op080_3StringMap["SN_2"].Addr, _op080_3StringMap["SN_2"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op080_3IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op080_3IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op080_3IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op080_3IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op080_3IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op080_3IntMap["产品总结果"]) },
+ { "压机结果", ReadPlcIntAsync(plc, _op080_3IntMap["压机结果"]) },
+ { "左螺丝枪结果", ReadPlcIntAsync(plc, _op080_3IntMap["左螺丝枪结果"]) },
+ { "右螺丝枪结果", ReadPlcIntAsync(plc, _op080_3IntMap["右螺丝枪结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op080_3IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "压机左压力值", ReadPlcRealAsync(plc, _op080_3IntMap["压机左压力值"]) },
+ { "压机右压力值", ReadPlcRealAsync(plc, _op080_3IntMap["压机右压力值"]) },
+ { "压机行程值", ReadPlcRealAsync(plc, _op080_3IntMap["压机行程值"]) },
+ { "保压时间", ReadPlcRealAsync(plc, _op080_3IntMap["保压时间"]) },
+ { "左螺丝枪扭矩", ReadPlcRealAsync(plc, _op080_3IntMap["左螺丝枪扭矩"]) },
+ { "左螺丝枪角度", ReadPlcRealAsync(plc, _op080_3IntMap["左螺丝枪角度"]) },
+ { "左螺丝枪深度", ReadPlcRealAsync(plc, _op080_3IntMap["左螺丝枪深度"]) },
+ { "左螺丝枪时间", ReadPlcRealAsync(plc, _op080_3IntMap["左螺丝枪时间"]) },
+ { "右螺丝枪扭矩", ReadPlcRealAsync(plc, _op080_3IntMap["右螺丝枪扭矩"]) },
+ { "右螺丝枪角度", ReadPlcRealAsync(plc, _op080_3IntMap["右螺丝枪角度"]) },
+ { "右螺丝枪深度", ReadPlcRealAsync(plc, _op080_3IntMap["右螺丝枪深度"]) },
+ { "右螺丝枪时间", ReadPlcRealAsync(plc, _op080_3IntMap["右螺丝枪时间"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op080_3IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["SN_1"].Result ?? string.Empty;
+ var sn2 = stringTasks["SN_2"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var pressResult = intTasks["压机结果"].Result;
+ var leftScrewResult = intTasks["左螺丝枪结果"].Result;
+ var rightScrewResult = intTasks["右螺丝枪结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var pressLeftPressure = realTasks["压机左压力值"].Result;
+ var pressRightPressure = realTasks["压机右压力值"].Result;
+ var pressStroke = realTasks["压机行程值"].Result;
+ var pressHoldTime = realTasks["保压时间"].Result;
+ var leftScrewTorque = realTasks["左螺丝枪扭矩"].Result;
+ var leftScrewAngle = realTasks["左螺丝枪角度"].Result;
+ var leftScrewDepth = realTasks["左螺丝枪深度"].Result;
+ var leftScrewTime = realTasks["左螺丝枪时间"].Result;
+ var rightScrewTorque = realTasks["右螺丝枪扭矩"].Result;
+ var rightScrewAngle = realTasks["右螺丝枪角度"].Result;
+ var rightScrewDepth = realTasks["右螺丝枪深度"].Result;
+ var rightScrewTime = realTasks["右螺丝枪时间"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+
+ // 6. 构建完整实体(覆盖所有工艺参数字段)
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "PWM压装&CUP上料&拧紧工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 压机参数
+ PinPressure1 = pressLeftPressure.ToString("F2"),//压机左压力值
+ PinPressure2 = pressRightPressure.ToString("F2"),//压机右压力值
+ PinStroke1 = pressStroke.ToString("F2"),//压机行程值
+ PressHoldTime = pressHoldTime.ToString(),//保压时间
+
+ // 左螺丝枪参数
+ Screw1Result = leftScrewResult.ToString(),
+ Screw1Torque = leftScrewTorque.ToString("F2"),
+ Screw1Depth = leftScrewDepth.ToString("F2"),
+ Screw1Angle = leftScrewAngle.ToString("F2"),
+ Screw1TightenTime = leftScrewTime.ToString("F2"),
+
+ // 右螺丝枪参数
+ Screw2Result = rightScrewResult.ToString(),
+ Screw2Torque = rightScrewTorque.ToString("F2"),
+ Screw2Depth = rightScrewDepth.ToString("F2"),
+ Screw2Angle = rightScrewAngle.ToString("F2"),
+ Screw2TightenTime = rightScrewTime.ToString("F2"),
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP080-3读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP085数据(自动上料到波峰焊工位,DB1001)
+ ///
+ public async Task ReadOP085DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op085StringMap["产品型号"].Addr, _op085StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op085StringMap["产品名称"].Addr, _op085StringMap["产品名称"].Len) },
+ { "波峰焊托盘条码", ReadPlcStringAsync(plc, _op085StringMap["波峰焊托盘条码"].Addr, _op085StringMap["波峰焊托盘条码"].Len) },
+ { "穴位1产品SN", ReadPlcStringAsync(plc, _op085StringMap["穴位1产品SN"].Addr, _op085StringMap["穴位1产品SN"].Len) },
+ { "穴位2产品SN", ReadPlcStringAsync(plc, _op085StringMap["穴位2产品SN"].Addr, _op085StringMap["穴位2产品SN"].Len) },
+ { "穴位3产品SN", ReadPlcStringAsync(plc, _op085StringMap["穴位3产品SN"].Addr, _op085StringMap["穴位3产品SN"].Len) },
+ { "穴位4产品SN", ReadPlcStringAsync(plc, _op085StringMap["穴位4产品SN"].Addr, _op085StringMap["穴位4产品SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op085IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op085IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op085IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op085IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op085IntMap["实际产量"]) },
+ { "线体托盘号", ReadPlcIntAsync(plc, _op085IntMap["线体托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "节拍时间", ReadPlcRealAsync(plc, _op085IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var trayBarcode = stringTasks["波峰焊托盘条码"].Result ?? string.Empty;
+ var sn1 = stringTasks["穴位1产品SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["穴位2产品SN"].Result ?? string.Empty;
+ var sn3 = stringTasks["穴位3产品SN"].Result ?? string.Empty;
+ var sn4 = stringTasks["穴位4产品SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var lineTrayNo = intTasks["线体托盘号"].Result.ToString();
+
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = "1"; // 上料工位默认合格
+
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "自动上料到波峰焊工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ Product1SN = sn1,
+ Product2SN = sn2,
+ Product3SN = sn3,
+ Product4SN = sn4,
+ TrayNo = lineTrayNo,
+ TrayBarcode = trayBarcode,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP085读取异常:{ex.Message}");
+ return null;
+ }
+ }
+ ///
+ /// 读取OP100数据(手动上料壳体&盖板工位,DB1001)
+ ///
+ public async Task ReadOP100DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op100StringMap["产品型号"].Addr, _op100StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op100StringMap["产品名称"].Addr, _op100StringMap["产品名称"].Len) },
+ { "产品SN", ReadPlcStringAsync(plc, _op100StringMap["产品SN"].Addr, _op100StringMap["产品SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op100IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op100IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op100IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op100IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op100IntMap["实际产量"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op100IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "节拍时间", ReadPlcRealAsync(plc, _op100IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["产品SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = "1"; // 手动上料工位默认合格
+
+
+ // 6. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "手动上料壳体&盖板工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC_System",
+ CreatedTime = now,
+
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP100读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP1011数据(HV连接器装配工位,DB1001)
+ ///
+ public async Task ReadOP1011DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op1011StringMap["产品型号"].Addr, _op1011StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op1011StringMap["产品名称"].Addr, _op1011StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op1011StringMap["查询SN"].Addr, _op1011StringMap["查询SN"].Len) },
+ { "上传结果SN", ReadPlcStringAsync(plc, _op1011StringMap["上传结果SN"].Addr, _op1011StringMap["上传结果SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op1011IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op1011IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op1011IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op1011IntMap["生产模式"]) },
+ { "螺钉枪程序号", ReadPlcIntAsync(plc, _op1011IntMap["螺钉枪程序号"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op1011IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op1011IntMap["产品总结果"]) },
+ { "1#结果", ReadPlcIntAsync(plc, _op1011IntMap["1#结果"]) },
+ { "2#结果", ReadPlcIntAsync(plc, _op1011IntMap["2#结果"]) },
+ { "3#结果", ReadPlcIntAsync(plc, _op1011IntMap["3#结果"]) },
+ { "4#结果", ReadPlcIntAsync(plc, _op1011IntMap["4#结果"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "1#扭矩", ReadPlcRealAsync(plc, _op1011IntMap["1#扭矩"]) },
+ { "2#扭矩", ReadPlcRealAsync(plc, _op1011IntMap["2#扭矩"]) },
+ { "3#扭矩", ReadPlcRealAsync(plc, _op1011IntMap["3#扭矩"]) },
+ { "4#扭矩", ReadPlcRealAsync(plc, _op1011IntMap["4#扭矩"]) },
+ { "1#转角", ReadPlcRealAsync(plc, _op1011IntMap["1#转角"]) },
+ { "2#转角", ReadPlcRealAsync(plc, _op1011IntMap["2#转角"]) },
+ { "3#转角", ReadPlcRealAsync(plc, _op1011IntMap["3#转角"]) },
+ { "4#转角", ReadPlcRealAsync(plc, _op1011IntMap["4#转角"]) },
+ { "1#深度", ReadPlcRealAsync(plc, _op1011IntMap["1#深度"]) },
+ { "2#深度", ReadPlcRealAsync(plc, _op1011IntMap["2#深度"]) },
+ { "3#深度", ReadPlcRealAsync(plc, _op1011IntMap["3#深度"]) },
+ { "4#深度", ReadPlcRealAsync(plc, _op1011IntMap["4#深度"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op1011IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["上传结果SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var screwGunProgram = intTasks["螺钉枪程序号"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var screw1Result = intTasks["1#结果"].Result;
+ var screw2Result = intTasks["2#结果"].Result;
+ var screw3Result = intTasks["3#结果"].Result;
+ var screw4Result = intTasks["4#结果"].Result;
+
+ var screw1Torque = realTasks["1#扭矩"].Result;
+ var screw2Torque = realTasks["2#扭矩"].Result;
+ var screw3Torque = realTasks["3#扭矩"].Result;
+ var screw4Torque = realTasks["4#扭矩"].Result;
+ var screw1Angle = realTasks["1#转角"].Result;
+ var screw2Angle = realTasks["2#转角"].Result;
+ var screw3Angle = realTasks["3#转角"].Result;
+ var screw4Angle = realTasks["4#转角"].Result;
+ var screw1Depth = realTasks["1#深度"].Result;
+ var screw2Depth = realTasks["2#深度"].Result;
+ var screw3Depth = realTasks["3#深度"].Result;
+ var screw4Depth = realTasks["4#深度"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "HV连接器装配工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 螺丝1-4参数完整赋值
+ Screw1Result = screw1Result.ToString(),
+ Screw1Torque = screw1Torque.ToString("F2"),
+ Screw1Depth = screw1Depth.ToString("F2"),
+ Screw1Angle = screw1Angle.ToString("F2"),
+ Screw2Result = screw2Result.ToString(),
+ Screw2Torque = screw2Torque.ToString("F2"),
+ Screw2Depth = screw2Depth.ToString("F2"),
+ Screw2Angle = screw2Angle.ToString("F2"),
+ Screw3Result = screw3Result.ToString(),
+ Screw3Torque = screw3Torque.ToString("F2"),
+ Screw3Depth = screw3Depth.ToString("F2"),
+ Screw3Angle = screw3Angle.ToString("F2"),
+ Screw4Result = screw4Result.ToString(),
+ Screw4Torque = screw4Torque.ToString("F2"),
+ Screw4Depth = screw4Depth.ToString("F2"),
+ Screw4Angle = screw4Angle.ToString("F2"),
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP1011读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP1012数据(Ring terminal装配工位,DB1001)
+ ///
+ public async Task ReadOP1012DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op1012StringMap["产品型号"].Addr, _op1012StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op1012StringMap["产品名称"].Addr, _op1012StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op1012StringMap["查询SN"].Addr, _op1012StringMap["查询SN"].Len) },
+ { "上传SN", ReadPlcStringAsync(plc, _op1012StringMap["上传SN"].Addr, _op1012StringMap["上传SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op1012IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op1012IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op1012IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op1012IntMap["生产模式"]) },
+ { "螺钉枪程序号", ReadPlcIntAsync(plc, _op1012IntMap["螺钉枪程序号"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op1012IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op1012IntMap["产品总结果"]) },
+ { "1#结果", ReadPlcIntAsync(plc, _op1012IntMap["1#结果"]) },
+ { "2#结果", ReadPlcIntAsync(plc, _op1012IntMap["2#结果"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "1#扭矩", ReadPlcRealAsync(plc, _op1012IntMap["1#扭矩"]) },
+ { "2#扭矩", ReadPlcRealAsync(plc, _op1012IntMap["2#扭矩"]) },
+ { "1#转角", ReadPlcRealAsync(plc, _op1012IntMap["1#转角"]) },
+ { "2#转角", ReadPlcRealAsync(plc, _op1012IntMap["2#转角"]) },
+ { "1#深度", ReadPlcRealAsync(plc, _op1012IntMap["1#深度"]) },
+ { "2#深度", ReadPlcRealAsync(plc, _op1012IntMap["2#深度"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op1012IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["上传SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var screwGunProgram = intTasks["螺钉枪程序号"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var screw1Result = intTasks["1#结果"].Result;
+ var screw2Result = intTasks["2#结果"].Result;
+
+ var screw1Torque = realTasks["1#扭矩"].Result;
+ var screw2Torque = realTasks["2#扭矩"].Result;
+ var screw1Angle = realTasks["1#转角"].Result;
+ var screw2Angle = realTasks["2#转角"].Result;
+ var screw1Depth = realTasks["1#深度"].Result;
+ var screw2Depth = realTasks["2#深度"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "Ring terminal装配工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC_System",
+ CreatedTime = now,
+ UpdatedBy = "PLC_System",
+ UpdatedTime = now,
+ ParamName = "Ring terminal装配参数",
+ ParamValue = $"总结果:{qualificationFlag},产量:{actualOutput},螺钉枪程序号:{screwGunProgram}",
+
+ // 螺丝1-2参数完整赋值
+ Screw1Result = screw1Result.ToString(),
+ Screw1Torque = screw1Torque.ToString("F2"),
+ Screw1Depth = screw1Depth.ToString("F2"),
+ Screw1Angle = screw1Angle.ToString("F2"),
+ Screw2Result = screw2Result.ToString(),
+ Screw2Torque = screw2Torque.ToString("F2"),
+ Screw2Depth = screw2Depth.ToString("F2"),
+ Screw2Angle = screw2Angle.ToString("F2"),
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP1012读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP102数据(等离子处理工位,DB1001)
+ ///
+ public async Task ReadOP102DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op102StringMap["产品型号"].Addr, _op102StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op102StringMap["产品名称"].Addr, _op102StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op102StringMap["查询SN"].Addr, _op102StringMap["查询SN"].Len) },
+ { "上传结果SN", ReadPlcStringAsync(plc, _op102StringMap["上传结果SN"].Addr, _op102StringMap["上传结果SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op102IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op102IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op102IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op102IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op102IntMap["实际产量"]) },
+ { "站位结果", ReadPlcIntAsync(plc, _op102IntMap["站位结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op102IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "节拍时间", ReadPlcRealAsync(plc, _op102IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["上传结果SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var stationResult = intTasks["站位结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = stationResult == 1 ? "1" : "2";
+
+ // 6. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "等离子处理工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP102读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP110-1数据(点胶封胶Q3-3636工位,DB1001)
+ ///
+ public async Task ReadOP110_1DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op110_1StringMap["产品型号"].Addr, _op110_1StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op110_1StringMap["产品名称"].Addr, _op110_1StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op110_1StringMap["查询SN"].Addr, _op110_1StringMap["查询SN"].Len) },
+ { "上传结果SN", ReadPlcStringAsync(plc, _op110_1StringMap["上传结果SN"].Addr, _op110_1StringMap["上传结果SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op110_1IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op110_1IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op110_1IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op110_1IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op110_1IntMap["实际产量"]) },
+ { "相机结果", ReadPlcIntAsync(plc, _op110_1IntMap["相机结果"]) },
+ { "站位结果", ReadPlcIntAsync(plc, _op110_1IntMap["站位结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op110_1IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "节拍时间", ReadPlcRealAsync(plc, _op110_1IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["上传结果SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var cameraResult = intTasks["相机结果"].Result;
+ var stationResult = intTasks["站位结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = stationResult == 1 ? "1" : "2";
+
+ // 6. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "点胶封胶Q3-3636工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC_System",
+ CreatedTime = now,
+ CameraResult = cameraResult == 1 ? "1" : "2", // 相机结果映射
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP110-1读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP110-2数据(盖板组装&拧紧工位,DB1001)
+ ///
+ public async Task ReadOP110_2DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op110_2StringMap["产品型号"].Addr, _op110_2StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op110_2StringMap["产品名称"].Addr, _op110_2StringMap["产品名称"].Len) },
+ { "合装工位查询SN", ReadPlcStringAsync(plc, _op110_2StringMap["合装工位查询SN"].Addr, _op110_2StringMap["合装工位查询SN"].Len) },
+ { "拧紧工位上传结果SN", ReadPlcStringAsync(plc, _op110_2StringMap["拧紧工位上传结果SN"].Addr, _op110_2StringMap["拧紧工位上传结果SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op110_2IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op110_2IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op110_2IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op110_2IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op110_2IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op110_2IntMap["产品总结果"]) },
+ { "3#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["3#螺丝结果"]) },
+ { "5#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["5#螺丝结果"]) },
+ { "6#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["6#螺丝结果"]) },
+ { "1#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["1#螺丝结果"]) },
+ { "2#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["2#螺丝结果"]) },
+ { "4#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["4#螺丝结果"]) },
+ { "7#螺丝结果", ReadPlcIntAsync(plc, _op110_2IntMap["7#螺丝结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op110_2IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "3#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["3#扭矩"]) },
+ { "3#深度", ReadPlcRealAsync(plc, _op110_2IntMap["3#深度"]) },
+ { "3#角度", ReadPlcRealAsync(plc, _op110_2IntMap["3#角度"]) },
+ { "3#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["3#拧紧时间"]) },
+ { "5#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["5#扭矩"]) },
+ { "5#深度", ReadPlcRealAsync(plc, _op110_2IntMap["5#深度"]) },
+ { "5#角度", ReadPlcRealAsync(plc, _op110_2IntMap["5#角度"]) },
+ { "5#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["5#拧紧时间"]) },
+ { "6#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["6#扭矩"]) },
+ { "6#深度", ReadPlcRealAsync(plc, _op110_2IntMap["6#深度"]) },
+ { "6#角度", ReadPlcRealAsync(plc, _op110_2IntMap["6#角度"]) },
+ { "6#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["6#拧紧时间"]) },
+ { "1#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["1#扭矩"]) },
+ { "1#深度", ReadPlcRealAsync(plc, _op110_2IntMap["1#深度"]) },
+ { "1#角度", ReadPlcRealAsync(plc, _op110_2IntMap["1#角度"]) },
+ { "1#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["1#拧紧时间"]) },
+ { "2#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["2#扭矩"]) },
+ { "2#深度", ReadPlcRealAsync(plc, _op110_2IntMap["2#深度"]) },
+ { "2#角度", ReadPlcRealAsync(plc, _op110_2IntMap["2#角度"]) },
+ { "2#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["2#拧紧时间"]) },
+ { "4#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["4#扭矩"]) },
+ { "4#深度", ReadPlcRealAsync(plc, _op110_2IntMap["4#深度"]) },
+ { "4#角度", ReadPlcRealAsync(plc, _op110_2IntMap["4#角度"]) },
+ { "4#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["4#拧紧时间"]) },
+ { "7#扭矩", ReadPlcRealAsync(plc, _op110_2IntMap["7#扭矩"]) },
+ { "7#深度", ReadPlcRealAsync(plc, _op110_2IntMap["7#深度"]) },
+ { "7#角度", ReadPlcRealAsync(plc, _op110_2IntMap["7#角度"]) },
+ { "7#拧紧时间", ReadPlcRealAsync(plc, _op110_2IntMap["7#拧紧时间"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op110_2IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["合装工位查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["拧紧工位上传结果SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var screw1Result = intTasks["1#螺丝结果"].Result;
+ var screw2Result = intTasks["2#螺丝结果"].Result;
+ var screw3Result = intTasks["3#螺丝结果"].Result;
+ var screw4Result = intTasks["4#螺丝结果"].Result;
+ var screw5Result = intTasks["5#螺丝结果"].Result;
+ var screw6Result = intTasks["6#螺丝结果"].Result;
+ var screw7Result = intTasks["7#螺丝结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var screw1Torque = realTasks["1#扭矩"].Result;
+ var screw1Depth = realTasks["1#深度"].Result;
+ var screw1Angle = realTasks["1#角度"].Result;
+ var screw1TightenTime = realTasks["1#拧紧时间"].Result;
+ var screw2Torque = realTasks["2#扭矩"].Result;
+ var screw2Depth = realTasks["2#深度"].Result;
+ var screw2Angle = realTasks["2#角度"].Result;
+ var screw2TightenTime = realTasks["2#拧紧时间"].Result;
+ var screw3Torque = realTasks["3#扭矩"].Result;
+ var screw3Depth = realTasks["3#深度"].Result;
+ var screw3Angle = realTasks["3#角度"].Result;
+ var screw3TightenTime = realTasks["3#拧紧时间"].Result;
+ var screw4Torque = realTasks["4#扭矩"].Result;
+ var screw4Depth = realTasks["4#深度"].Result;
+ var screw4Angle = realTasks["4#角度"].Result;
+ var screw4TightenTime = realTasks["4#拧紧时间"].Result;
+ var screw5Torque = realTasks["5#扭矩"].Result;
+ var screw5Depth = realTasks["5#深度"].Result;
+ var screw5Angle = realTasks["5#角度"].Result;
+ var screw5TightenTime = realTasks["5#拧紧时间"].Result;
+ var screw6Torque = realTasks["6#扭矩"].Result;
+ var screw6Depth = realTasks["6#深度"].Result;
+ var screw6Angle = realTasks["6#角度"].Result;
+ var screw6TightenTime = realTasks["6#拧紧时间"].Result;
+ var screw7Torque = realTasks["7#扭矩"].Result;
+ var screw7Depth = realTasks["7#深度"].Result;
+ var screw7Angle = realTasks["7#角度"].Result;
+ var screw7TightenTime = realTasks["7#拧紧时间"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 6. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "盖板组装&拧紧工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 螺丝1-7参数完整赋值
+ Screw1Result = screw1Result.ToString(),
+ Screw1Torque = screw1Torque.ToString("F2"),
+ Screw1Depth = screw1Depth.ToString("F2"),
+ Screw1Angle = screw1Angle.ToString("F2"),
+ Screw1TightenTime = screw1TightenTime.ToString("F2"),
+ Screw2Result = screw2Result.ToString(),
+ Screw2Torque = screw2Torque.ToString("F2"),
+ Screw2Depth = screw2Depth.ToString("F2"),
+ Screw2Angle = screw2Angle.ToString("F2"),
+ Screw2TightenTime = screw2TightenTime.ToString("F2"),
+ Screw3Result = screw3Result.ToString(),
+ Screw3Torque = screw3Torque.ToString("F2"),
+ Screw3Depth = screw3Depth.ToString("F2"),
+ Screw3Angle = screw3Angle.ToString("F2"),
+ Screw3TightenTime = screw3TightenTime.ToString("F2"),
+ Screw4Result = screw4Result.ToString(),
+ Screw4Torque = screw4Torque.ToString("F2"),
+ Screw4Depth = screw4Depth.ToString("F2"),
+ Screw4Angle = screw4Angle.ToString("F2"),
+ Screw4TightenTime = screw4TightenTime.ToString("F2"),
+ Screw5Result = screw5Result.ToString(),
+ Screw5Torque = screw5Torque.ToString("F2"),
+ Screw5Depth = screw5Depth.ToString("F2"),
+ Screw5Angle = screw5Angle.ToString("F2"),
+ Screw5TightenTime = screw5TightenTime.ToString("F2"),
+ Screw6Result = screw6Result.ToString(),
+ Screw6Torque = screw6Torque.ToString("F2"),
+ Screw6Depth = screw6Depth.ToString("F2"),
+ Screw6Angle = screw6Angle.ToString("F2"),
+ Screw6TightenTime = screw6TightenTime.ToString("F2"),
+ Screw7Result = screw7Result.ToString(),
+ Screw7Torque = screw7Torque.ToString("F2"),
+ Screw7Depth = screw7Depth.ToString("F2"),
+ Screw7Angle = screw7Angle.ToString("F2"),
+ Screw7TightenTime = screw7TightenTime.ToString("F2"),
+
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP110-2读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP110-3数据(盖板拧紧工位,DB1001)
+ ///
+ public async Task ReadOP110_3DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op110_3StringMap["产品型号"].Addr, _op110_3StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op110_3StringMap["产品名称"].Addr, _op110_3StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op110_3StringMap["查询SN"].Addr, _op110_3StringMap["查询SN"].Len) },
+ { "保存SN", ReadPlcStringAsync(plc, _op110_3StringMap["保存SN"].Addr, _op110_3StringMap["保存SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op110_3IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op110_3IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op110_3IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op110_3IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op110_3IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op110_3IntMap["产品总结果"]) },
+ { "1#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["1#螺丝结果"]) },
+ { "2#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["2#螺丝结果"]) },
+ { "3#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["3#螺丝结果"]) },
+ { "4#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["4#螺丝结果"]) },
+ { "5#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["5#螺丝结果"]) },
+ { "6#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["6#螺丝结果"]) },
+ { "7#螺丝结果", ReadPlcIntAsync(plc, _op110_3IntMap["7#螺丝结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op110_3IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "1#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["1#扭矩"]) },
+ { "1#深度", ReadPlcRealAsync(plc, _op110_3IntMap["1#深度"]) },
+ { "1#角度", ReadPlcRealAsync(plc, _op110_3IntMap["1#角度"]) },
+ { "1#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["1#拧紧时间"]) },
+ { "2#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["2#扭矩"]) },
+ { "2#深度", ReadPlcRealAsync(plc, _op110_3IntMap["2#深度"]) },
+ { "2#角度", ReadPlcRealAsync(plc, _op110_3IntMap["2#角度"]) },
+ { "2#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["2#拧紧时间"]) },
+ { "3#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["3#扭矩"]) },
+ { "3#深度", ReadPlcRealAsync(plc, _op110_3IntMap["3#深度"]) },
+ { "3#角度", ReadPlcRealAsync(plc, _op110_3IntMap["3#角度"]) },
+ { "3#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["3#拧紧时间"]) },
+ { "4#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["4#扭矩"]) },
+ { "4#深度", ReadPlcRealAsync(plc, _op110_3IntMap["4#深度"]) },
+ { "4#角度", ReadPlcRealAsync(plc, _op110_3IntMap["4#角度"]) },
+ { "4#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["4#拧紧时间"]) },
+ { "5#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["5#扭矩"]) },
+ { "5#深度", ReadPlcRealAsync(plc, _op110_3IntMap["5#深度"]) },
+ { "5#角度", ReadPlcRealAsync(plc, _op110_3IntMap["5#角度"]) },
+ { "5#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["5#拧紧时间"]) },
+ { "6#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["6#扭矩"]) },
+ { "6#深度", ReadPlcRealAsync(plc, _op110_3IntMap["6#深度"]) },
+ { "6#角度", ReadPlcRealAsync(plc, _op110_3IntMap["6#角度"]) },
+ { "6#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["6#拧紧时间"]) },
+ { "7#扭矩", ReadPlcRealAsync(plc, _op110_3IntMap["7#扭矩"]) },
+ { "7#深度", ReadPlcRealAsync(plc, _op110_3IntMap["7#深度"]) },
+ { "7#角度", ReadPlcRealAsync(plc, _op110_3IntMap["7#角度"]) },
+ { "7#拧紧时间", ReadPlcRealAsync(plc, _op110_3IntMap["7#拧紧时间"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op110_3IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["保存SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var screw1Result = intTasks["1#螺丝结果"].Result;
+ var screw2Result = intTasks["2#螺丝结果"].Result;
+ var screw3Result = intTasks["3#螺丝结果"].Result;
+ var screw4Result = intTasks["4#螺丝结果"].Result;
+ var screw5Result = intTasks["5#螺丝结果"].Result;
+ var screw6Result = intTasks["6#螺丝结果"].Result;
+ var screw7Result = intTasks["7#螺丝结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var screw1Torque = realTasks["1#扭矩"].Result;
+ var screw1Depth = realTasks["1#深度"].Result;
+ var screw1Angle = realTasks["1#角度"].Result;
+ var screw1TightenTime = realTasks["1#拧紧时间"].Result;
+ var screw2Torque = realTasks["2#扭矩"].Result;
+ var screw2Depth = realTasks["2#深度"].Result;
+ var screw2Angle = realTasks["2#角度"].Result;
+ var screw2TightenTime = realTasks["2#拧紧时间"].Result;
+ var screw3Torque = realTasks["3#扭矩"].Result;
+ var screw3Depth = realTasks["3#深度"].Result;
+ var screw3Angle = realTasks["3#角度"].Result;
+ var screw3TightenTime = realTasks["3#拧紧时间"].Result;
+ var screw4Torque = realTasks["4#扭矩"].Result;
+ var screw4Depth = realTasks["4#深度"].Result;
+ var screw4Angle = realTasks["4#角度"].Result;
+ var screw4TightenTime = realTasks["4#拧紧时间"].Result;
+ var screw5Torque = realTasks["5#扭矩"].Result;
+ var screw5Depth = realTasks["5#深度"].Result;
+ var screw5Angle = realTasks["5#角度"].Result;
+ var screw5TightenTime = realTasks["5#拧紧时间"].Result;
+ var screw6Torque = realTasks["6#扭矩"].Result;
+ var screw6Depth = realTasks["6#深度"].Result;
+ var screw6Angle = realTasks["6#角度"].Result;
+ var screw6TightenTime = realTasks["6#拧紧时间"].Result;
+ var screw7Torque = realTasks["7#扭矩"].Result;
+ var screw7Depth = realTasks["7#深度"].Result;
+ var screw7Angle = realTasks["7#角度"].Result;
+ var screw7TightenTime = realTasks["7#拧紧时间"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "盖板拧紧工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 螺丝1-7参数完整赋值
+ Screw1Result = screw1Result.ToString(),
+ Screw1Torque = screw1Torque.ToString("F2"),
+ Screw1Depth = screw1Depth.ToString("F2"),
+ Screw1Angle = screw1Angle.ToString("F2"),
+ Screw1TightenTime = screw1TightenTime.ToString("F2"),
+ Screw2Result = screw2Result.ToString(),
+ Screw2Torque = screw2Torque.ToString("F2"),
+ Screw2Depth = screw2Depth.ToString("F2"),
+ Screw2Angle = screw2Angle.ToString("F2"),
+ Screw2TightenTime = screw2TightenTime.ToString("F2"),
+ Screw3Result = screw3Result.ToString(),
+ Screw3Torque = screw3Torque.ToString("F2"),
+ Screw3Depth = screw3Depth.ToString("F2"),
+ Screw3Angle = screw3Angle.ToString("F2"),
+ Screw3TightenTime = screw3TightenTime.ToString("F2"),
+ Screw4Result = screw4Result.ToString(),
+ Screw4Torque = screw4Torque.ToString("F2"),
+ Screw4Depth = screw4Depth.ToString("F2"),
+ Screw4Angle = screw4Angle.ToString("F2"),
+ Screw4TightenTime = screw4TightenTime.ToString("F2"),
+ Screw5Result = screw5Result.ToString(),
+ Screw5Torque = screw5Torque.ToString("F2"),
+ Screw5Depth = screw5Depth.ToString("F2"),
+ Screw5Angle = screw5Angle.ToString("F2"),
+ Screw5TightenTime = screw5TightenTime.ToString("F2"),
+ Screw6Result = screw6Result.ToString(),
+ Screw6Torque = screw6Torque.ToString("F2"),
+ Screw6Depth = screw6Depth.ToString("F2"),
+ Screw6Angle = screw6Angle.ToString("F2"),
+ Screw6TightenTime = screw6TightenTime.ToString("F2"),
+ Screw7Result = screw7Result.ToString(),
+ Screw7Torque = screw7Torque.ToString("F2"),
+ Screw7Depth = screw7Depth.ToString("F2"),
+ Screw7Angle = screw7Angle.ToString("F2"),
+ Screw7TightenTime = screw7TightenTime.ToString("F2"),
+
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP110-3读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP115数据(自动上下料到固化炉工位,DB1001)
+ ///
+ public async Task ReadOP115DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op115StringMap["产品型号"].Addr, _op115StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op115StringMap["产品名称"].Addr, _op115StringMap["产品名称"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op115IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op115IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op115IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op115IntMap["生产模式"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = "1"; // 上下料工位默认合格
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "自动上下料到固化炉工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ CreatedBy = "PLC",
+ CreatedTime = now,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP115读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP140数据(气密性测试工位,DB1001)
+ ///
+ public async Task ReadOP140DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op140StringMap["产品型号"].Addr, _op140StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op140StringMap["产品名称"].Addr, _op140StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op140StringMap["查询SN"].Addr, _op140StringMap["查询SN"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op140IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op140IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op140IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op140IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op140IntMap["实际产量"]) },
+ { "产品结果", ReadPlcIntAsync(plc, _op140IntMap["产品结果"]) },
+ { "Socket", ReadPlcIntAsync(plc, _op140IntMap["Socket"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op140IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "压力值", ReadPlcRealAsync(plc, _op140IntMap["压力值"]) },
+ { "泄露值", ReadPlcRealAsync(plc, _op140IntMap["泄露值"]) },
+ { "节拍时间", ReadPlcRealAsync(plc, _op140IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productResult = intTasks["产品结果"].Result;
+ var socket = intTasks["Socket"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var pressure = realTasks["压力值"].Result;
+ var leak = realTasks["泄露值"].Result;
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productResult == 1 ? "1" : "2";
+
+ // 5. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "气密性测试工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+
+ // 测试参数
+ PinPressure1 = pressure.ToString("F2"),
+ PinPressure2 = leak.ToString("F2"),
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP140读取异常:{ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 读取OP165数据(自动贴标工位,DB1001)
+ ///
+ public async Task ReadOP165DataAsync(Plc plc, string ip, string workstationCode)
+ {
+ // 前置校验:快速失败
+ if (plc == null || !plc.IsConnected) return null;
+ if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(workstationCode))
+ throw new ArgumentNullException("IP或工位编码不能为空");
+
+ try
+ {
+ // 1. 批量创建并行读取任务
+ var stringTasks = new Dictionary>
+ {
+ { "产品型号", ReadPlcStringAsync(plc, _op165StringMap["产品型号"].Addr, _op165StringMap["产品型号"].Len) },
+ { "产品名称", ReadPlcStringAsync(plc, _op165StringMap["产品名称"].Addr, _op165StringMap["产品名称"].Len) },
+ { "查询SN", ReadPlcStringAsync(plc, _op165StringMap["查询SN"].Addr, _op165StringMap["查询SN"].Len) },
+ { "结果SN", ReadPlcStringAsync(plc, _op165StringMap["结果SN"].Addr, _op165StringMap["结果SN"].Len) },
+ { "二维码内容", ReadPlcStringAsync(plc, _op165StringMap["二维码内容"].Addr, _op165StringMap["二维码内容"].Len) },
+ { "下料工位条码", ReadPlcStringAsync(plc, _op165StringMap["下料工位条码"].Addr, _op165StringMap["下料工位条码"].Len) }
+ };
+
+ var intTasks = new Dictionary>
+ {
+ { "运行状态", ReadPlcIntAsync(plc, _op165IntMap["运行状态"]) },
+ { "设备模式", ReadPlcIntAsync(plc, _op165IntMap["设备模式"]) },
+ { "设备在线状态", ReadPlcIntAsync(plc, _op165IntMap["设备在线状态"]) },
+ { "生产模式", ReadPlcIntAsync(plc, _op165IntMap["生产模式"]) },
+ { "实际产量", ReadPlcIntAsync(plc, _op165IntMap["实际产量"]) },
+ { "产品总结果", ReadPlcIntAsync(plc, _op165IntMap["产品总结果"]) },
+ { "轴承检测结果", ReadPlcIntAsync(plc, _op165IntMap["轴承检测结果"]) },
+ { "贴标拍照结果", ReadPlcIntAsync(plc, _op165IntMap["贴标拍照结果"]) },
+ { "托盘号", ReadPlcIntAsync(plc, _op165IntMap["托盘号"]) }
+ };
+
+ var realTasks = new Dictionary>
+ {
+ { "节拍时间", ReadPlcRealAsync(plc, _op165IntMap["节拍时间"]) }
+ };
+
+ // 2. 并行等待所有任务完成
+ var allTasks = new List();
+ allTasks.AddRange(stringTasks.Values);
+ allTasks.AddRange(intTasks.Values);
+ allTasks.AddRange(realTasks.Values);
+ await Task.WhenAll(allTasks).ConfigureAwait(false);
+
+ // 3. 提取结果
+ var now = DateTime.Now;
+ var productModel = stringTasks["产品型号"].Result ?? string.Empty;
+ var productName = stringTasks["产品名称"].Result ?? string.Empty;
+ var sn1 = stringTasks["查询SN"].Result ?? string.Empty;
+ var sn2 = stringTasks["结果SN"].Result ?? string.Empty;
+ var qrCode = stringTasks["二维码内容"].Result ?? string.Empty;
+ var outFeedBarcode = stringTasks["下料工位条码"].Result ?? string.Empty;
+
+ var runStatus = intTasks["运行状态"].Result;
+ var machineModel = intTasks["设备模式"].Result;
+ var onlineStatus = intTasks["设备在线状态"].Result;
+ var produceModel = intTasks["生产模式"].Result;
+ var actualOutput = intTasks["实际产量"].Result;
+ var productTotalResult = intTasks["产品总结果"].Result;
+ var bearingResult = intTasks["轴承检测结果"].Result;
+ var labelPhotoResult = intTasks["贴标拍照结果"].Result;
+ var trayNo = intTasks["托盘号"].Result.ToString();
+
+ var cycleTime = realTasks["节拍时间"].Result;
+
+ // 4. 业务逻辑转换
+ var reworkFlag = produceModel == 2 ? "1" : "0";
+ var produceModelDesc = produceModel switch
+ {
+ 1 => "点检模式",
+ 2 => "返工模式",
+ 4 => "样件模式",
+ 5 => "正常模式",
+ _ => produceModel.ToString()
+ };
+ var onlineStatusDesc = onlineStatus == 1 ? "离线" : "在线";
+ var qualificationFlag = productTotalResult == 1 ? "1" : "2";
+
+ // 6. 构建完整实体
+ return new PlcProductionData
+ {
+ // 基础字段
+ PlcIp = ip,
+ OccurTime = now,
+ LineCode = "line2",
+ WorkstationCode = workstationCode,
+ WorkstationName = "自动贴标工位",
+ ProductModel = productModel,
+ ProductName = productName,
+ ProductCode = sn1,
+ SN1 = sn1,
+ SN2 = sn2,
+ TrayNo = trayNo,
+ ReworkFlag = reworkFlag,
+ Automanual = machineModel,
+ Runstatus = runStatus,
+ OnlineStatus = onlineStatusDesc,
+ ProduceModel = produceModelDesc,
+ QualificationFlag = qualificationFlag,
+ ProductionCycle = (int)Math.Round(cycleTime),
+ CreatedBy = "PLC",
+ CreatedTime = now,
+ CameraResult = labelPhotoResult == 1 ? "1" : "2", // 贴标拍照结果映射
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] OP165读取异常:{ex.Message}");
+ return null;
+ }
+ }
#endregion
// 可选:添加连接池清理方法(防止长期运行导致连接泄露)
@@ -2388,32 +5247,48 @@ namespace RIZO.Admin.WebApi.PLC.Service
return 0;
}
}
-
private async Task ReadPlcRealAsync(Plc plc, string addr)
{
- if (plc == null || string.IsNullOrWhiteSpace(addr))
- {
- Console.WriteLine($"Real读取失败:参数无效(地址:{addr})");
+ // 前置校验:快速过滤无效入参
+ if (plc is null || !plc.IsConnected || string.IsNullOrWhiteSpace(addr))
return 0.0f;
- }
+
try
{
- var val = await Task.Run(() => plc.Read(addr));
- Console.WriteLine($"Real地址[{addr}] 原始值:{val},类型:{val?.GetType().Name}");
- return val switch
+ // 地址解析:仅支持DBx.DBDy格式,增加容错
+ var parts = addr.Split('.');
+ if (parts.Length != 2 || !parts[0].StartsWith("DB") || !parts[1].StartsWith("DBD"))
+ return 0.0f;
+
+ if (!int.TryParse(parts[0].Substring(2), out int dbNumber) ||
+ !int.TryParse(parts[1].Substring(3), out int startByte))
+ return 0.0f;
+
+ // 核心读取:调用PLC非泛型读取方法
+ var result = await plc.ReadAsync(
+ DataType.DataBlock,
+ dbNumber,
+ startByte,
+ VarType.Real,
+ 1).ConfigureAwait(false);
+
+ // 关键修复:直接处理单个数值(非数组)
+ if (result != null)
{
- float f => f,
- double d => (float)d,
- int i => i,
- _ => 0.0f
- };
+ // 不管result是int/double/float,都强制转为float
+ return Convert.ToSingle(result);
+ }
+
+ // 无有效结果返回0
+ return 0.0f;
}
- catch (Exception ex)
+ catch
{
- Console.WriteLine($"Real读取失败(地址:{addr}):{ex.Message}");
+ // 异常兜底返回0
return 0.0f;
}
}
+
///
/// 格式化PLC读取的值,转为友好的字符串
///