EquipmentExecutor.cs
9.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
using HaHRCS.Rcs.Dal.Repository;
using HaHRCS.Rcs.Model.Entities;
using HHECS.BllModel;
using HHECS.Communication;
using HHECS.Communication.PLC;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Rcs.Executor.PLC;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace HaHRCS.Rcs.Executor.PLC
{
public class EquipmentExecutor : BackgroundService
{
#region 属性
/// <summary>
/// 设备
/// </summary>
public List<Equipment> equipment { get; set; }
/// <summary>
/// PLC交互属性
/// </summary>
public EquipmentCommunicationHub EquipmentCommunicationHub { get; set; }
public List<StationExecute> StationExecutes { get; private set; } = new List<StationExecute>();
public Guid InstanceId { get; } = Guid.NewGuid();
public object WriteFlag { get; set; } = false;
#endregion
private EquipmentRepository _equipmentRepository;
private EquipmentPropRepository _equipmentPropRepository;
private EquipmentTypeRepository _equipmentTypeRepository;
private EquipmentTypePropTemplateRepository _EquipmentTypePropTemplateRepository;
public EquipmentExecutor(EquipmentRepository equipmentRepository, EquipmentPropRepository equipmentPropRepository, EquipmentTypeRepository equipmentTypePropTemplate, EquipmentTypePropTemplateRepository equipmentTypePropTemplateRepository)
{
_equipmentRepository = equipmentRepository;
_equipmentPropRepository = equipmentPropRepository;
_equipmentTypeRepository = equipmentTypePropTemplate;
_EquipmentTypePropTemplateRepository = equipmentTypePropTemplateRepository;
}
public BllResult<List<Equipment>> InitEquipment()
{
try
{
var equipments = _equipmentRepository.Where(t => t.Disable == false).ToList();
var equipmentProps = _equipmentPropRepository.Where(t => true).ToList();
var equipmentTypes = _equipmentTypeRepository.Where(t => true).ToList();
var equipmentTypePropTemplates = _EquipmentTypePropTemplateRepository.Where(t => true).ToList();
//组合逻辑外键
equipments.ForEach(t =>
{
t.EquipmentType = equipmentTypes.FirstOrDefault(i => i.Id == t.EquipmentTypeId);
t.EquipmentProps = equipmentProps.Where(i => i.EquipmentId == t.Id).ToList();
});
equipmentProps.ForEach(t =>
{
t.Equipment = equipments.FirstOrDefault(i => i.Id == t.EquipmentId);
t.EquipmentTypePropTemplate = equipmentTypePropTemplates.FirstOrDefault(i => i.Id == t.EquipmentTypePropTemplateId);
});
//判断逻辑外键是否组合完毕
if (equipments.Count(t => t.EquipmentType == null || t.EquipmentProps.Count == 0) > 0)
{
return BllResultFactory.Error<List<Equipment>>("初始化设备信息失败,请检查基础数据", "ERROR");
}
//EquipmentList = equipments;
return BllResultFactory.Success(equipments);
}
catch (Exception ex)
{
return BllResultFactory.Exception<List<Equipment>>(ex, "初始化设备信息出错:" + ex.Message, "ERROR");
}
}
/// <summary>
/// 执行线程
/// </summary>
private void Excuting()
{
var groups = equipment.GroupBy(t => new { t.WarehouseCode, t.IP }).ToList();
foreach (var group in groups)
{
TaskExcutorModel taskExcutorModelMonitor = new TaskExcutorModel();
taskExcutorModelMonitor.EquipmentCodes = group.ToList().Select(t => t.Code).Aggregate((a, b) => a + "," + b);
taskExcutorModelMonitor.ExcuteTask = Task.Factory.StartNew(async () =>
{
Stopwatch stopwatch = new Stopwatch();
while (true)
{
//TestExcute(item.Key.IP);
await Task.Delay(100);
stopwatch.Restart();
var result = Excute(group.ToList(), group.Key.IP);
stopwatch.Stop();
taskExcutorModelMonitor.Time = stopwatch.ElapsedMilliseconds;
}
}, TaskCreationOptions.LongRunning).Unwrap();
}
}
private BllResult Excute(List<Equipment> equipments, string ip)
{
try
{
List<Equipment> tempEquipments = equipments;
if (EquipmentCommunicationHub == null)
{
return BllResultFactory.Error($"PLC为空", "Error01");
}
if (!EquipmentCommunicationHub.GetConnectStatus(ip).Success)
{
EquipmentCommunicationHub.DisConnect(ip);
var result2 = EquipmentCommunicationHub.Connect(ip);
if (!result2.Success)
{
return BllResultFactory.Error($"重新连接打开IP为{ip}的PLC连接失败:{result2.Msg};请检查网络是否断开", "Error02");
}
}
var readEquipments = tempEquipments.SelectMany(t => t.EquipmentProps)
.Where(a => a.EquipmentTypePropTemplate.PropType == EquipmentPropType.ECSReadAddress.ToString() ||
// a.EquipmentTypePropTemplate.PropType == EquipmentPropType.ECSWriteAddress.ToString() ||
a.EquipmentTypePropTemplate.PropType == EquipmentPropType.PLCAlarmAddress.ToString() ||
a.EquipmentTypePropTemplate.PropType == EquipmentPropType.PLCCollectionAddress.ToString())
.ToArray();
lock (WriteFlag)
{
var writeAddress = tempEquipments.SelectMany(t => t.EquipmentProps)
.Where(a => a.EquipmentTypePropTemplate.PropType == EquipmentPropType.ECSWriteAddress.ToString())
.ToArray();
var res= EquipmentCommunicationHub.Reads(writeAddress);
}
var result = EquipmentCommunicationHub.Reads(readEquipments);
#region 心跳
var heartbeat = tempEquipments.Find(t => t.EquipmentType.Code == EquipmentTypeConst.PLCHeartbeat.ToString() && t.IP == ip);
if (heartbeat == null)
{
return BllResultFactory.Error($"IP为{ip}的PLC没有配置心跳连接");
}
//var readProp = heartbeat.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == PLCHeartProps.PLCWrite.ToString());
var readProp = heartbeat.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == PLCHeartProps.PLCWrite.ToString());
var readResult = EquipmentCommunicationHub.Reads(readProp);
if (readResult.Success && readProp.Value == "True")
{
//回复一个
var prop = heartbeat.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == PLCHeartProps.WCSWrite.ToString());
prop.Value = "True";
EquipmentCommunicationHub.Writes(prop);
}
else
{
//表示心跳断开,排除其IP对应的设备
tempEquipments = tempEquipments.Where(t => t.IP != heartbeat.IP).ToList();
}
#endregion
//result.Success = true;
#region 站台、设备 处理
StationExecutes.ForEach(t =>
{
t.Excute(tempEquipments.Where(a => a.EquipmentType.Id == t.EquipmentType.Id).ToList(), EquipmentCommunicationHub, equipment);
});
#endregion
if (!result.Success)
{
return BllResultFactory.Error($"读取IP为{ip}的PLC地址错误:{result.Msg},如果此问题一直存在,请检查数据地址或网络配置", "Error03");
}
return BllResultFactory.Success("读取PLC成功");
}
catch (Exception ex)
{
return BllResultFactory.Error("程序处理出现异常");
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var result = EquipmentCommunicationHubBuilder.Build("HubBuilder3.x.json");
if (!result.Success)
{
result.Msg = $"初始化PLC失败:{result.Msg}";
return;
}
EquipmentCommunicationHub = result.Data;
var resut2 = InitEquipment();
if (!resut2.Success)
{
return;
}
equipment = resut2.Data;
equipment.Select(t => t.EquipmentType).Distinct().ToList().ForEach(t =>
{
if (t.Code == EquipmentTypeConst.Conving.ToString())
{
var conving = new ConvingExecute(t);
StationExecutes.Add(conving);
}
});
Excuting();
}
}
}