唐召明
authored
|
1
2
3
|
using HHECS.DAQClient.Common;
using HHECS.DAQClient.Model;
using HHECS.DAQClient.Communications;
|
唐召明
authored
|
4
|
using HslCommunication.Profinet.Siemens;
|
唐召明
authored
|
5
|
using HHECS.DAQClient.Dto;
|
唐召明
authored
|
6
|
using HHECS.EquipmentModel;
|
唐召明
authored
|
7
|
using System.Text.Json;
|
唐召明
authored
|
8
|
using System.Configuration;
|
唐召明
authored
|
9
|
using System.Collections.Concurrent;
|
唐召明
authored
|
10
|
using LinqKit;
|
唐召明
authored
|
11
|
|
唐召明
authored
|
12
|
namespace HHECS.DAQClient.Services
|
唐召明
authored
|
13
|
{
|
唐召明
authored
|
14
|
public class CenterService
|
唐召明
authored
|
15
|
{
|
唐召明
authored
|
16
|
public ConcurrentQueue<EquipmentDataQueue> EquipmentDataQueues = new ConcurrentQueue<EquipmentDataQueue>();
|
唐召明
authored
|
17
|
public List<EquipmentExtend> Equipments = new List<EquipmentExtend>();
|
唐召明
authored
|
18
|
|
唐召明
authored
|
19
|
private readonly SystemLog _log = SystemLog.GetInstance();
|
唐召明
authored
|
20
|
private readonly IFreeSql _freeSql;
|
唐召明
authored
|
21
22
|
private List<ICommunication> communications = new List<ICommunication>();
private CancellationTokenSource cts = new CancellationTokenSource();
|
唐召明
authored
|
23
|
|
唐召明
authored
|
24
25
26
27
28
29
|
/// <summary>
/// 当前区域
/// </summary>
/// <remarks>倘若指定了区域,则只加载该区域的数据</remarks>
private readonly string currentArea = string.Empty;
|
唐召明
authored
|
30
|
public CenterService(IFreeSql freeSql)
|
唐召明
authored
|
31
|
{
|
唐召明
authored
|
32
|
_freeSql = freeSql;
|
唐召明
authored
|
33
|
currentArea = ConfigurationManager.AppSettings["Area"];
|
唐召明
authored
|
34
35
36
37
38
39
40
41
|
}
/// <summary>
/// 重新加载设备信息并开始采集数据
/// </summary>
/// <returns></returns>
public void Start()
{
|
唐召明
authored
|
42
|
cts = new CancellationTokenSource();
|
唐召明
authored
|
43
44
|
try
{
|
唐召明
authored
|
45
46
|
if (string.IsNullOrWhiteSpace(currentArea))
{
|
唐召明
authored
|
47
|
Equipments = _freeSql.Queryable<EquipmentExtend>().Where(x => !x.Disable).ToList();
|
唐召明
authored
|
48
49
50
|
}
else
{
|
唐召明
authored
|
51
|
Equipments = _freeSql.Queryable<EquipmentExtend>().Where(x => !x.Disable && x.DestinationArea == currentArea).ToList();
|
唐召明
authored
|
52
|
}
|
唐召明
authored
|
53
|
if (Equipments.Count == 0)
|
唐召明
authored
|
54
|
{
|
唐召明
authored
|
55
|
_log.LogWarning($"设备数据为空,请配置数据后操作!");
|
唐召明
authored
|
56
57
58
|
cts.Cancel();
return;
}
|
唐召明
authored
|
59
|
|
唐召明
authored
|
60
61
|
var equipmentIds = Equipments.Select(x => x.Id).ToList();
var equipmentTypeIds = Equipments.Select(x => x.EquipmentTypeId).Distinct().ToList();
|
唐召明
authored
|
62
|
|
唐召明
authored
|
63
64
65
|
var equipmentProps = _freeSql.Queryable<EquipmentPropExtend>().Where(x => equipmentIds.Contains(x.EquipmentId)).ToList();
var equipmentTypes = _freeSql.Queryable<EquipmentTypeExtend>().Where(x => equipmentTypeIds.Contains(x.Id)).ToList();
var equipmentTypePropTemplates = _freeSql.Queryable<EquipmentTypePropTemplateExtend>().Where(x => equipmentTypeIds.Contains(x.EquipmentTypeId)).ToList();
|
唐召明
authored
|
66
|
//组合逻辑外键
|
唐召明
authored
|
67
|
Equipments.ForEach(t =>
|
唐召明
authored
|
68
69
70
71
72
73
|
{
t.EquipmentType = equipmentTypes.FirstOrDefault(i => i.Id == t.EquipmentTypeId);
t.EquipmentProps = equipmentProps.Where(i => i.EquipmentId == t.Id).ToList();
});
equipmentProps.ForEach(t =>
{
|
唐召明
authored
|
74
|
t.Equipment = Equipments.FirstOrDefault(i => i.Id == t.EquipmentId);
|
唐召明
authored
|
75
76
77
|
t.EquipmentTypePropTemplate = equipmentTypePropTemplates.FirstOrDefault(i => i.Id == t.EquipmentTypePropTemplateId);
});
|
唐召明
authored
|
78
79
80
|
var communicationConfigFliter = PredicateBuilder.New<CommunicationConfig>(true);
communicationConfigFliter = communicationConfigFliter.And(x => !x.Disable);
if (!string.IsNullOrWhiteSpace(currentArea))
|
唐召明
authored
|
81
|
{
|
唐召明
authored
|
82
|
var equipmentIPAddressList = Equipments.Select(x => x.IP).ToList();
|
唐召明
authored
|
83
|
communicationConfigFliter = communicationConfigFliter.And(x => equipmentIPAddressList.Contains(x.IpAddress));
|
唐召明
authored
|
84
85
|
}
|
唐召明
authored
|
86
87
|
var communicationConfigs = _freeSql.Queryable<CommunicationConfig>().Where(communicationConfigFliter).ToList();
|
唐召明
authored
|
88
89
90
91
92
93
94
95
|
if (communicationConfigs.Count == 0)
{
_log.LogWarning($"通讯配置数据为空,请配置数据后操作!");
cts.Cancel();
return;
}
communications = InitialCommunication(communicationConfigs);
|
唐召明
authored
|
96
97
98
99
100
101
102
103
104
|
//采集数据
foreach (var item in communications)
{
_ = Task.Run(async () =>
{
while (!cts.IsCancellationRequested)
{
try
{
|
唐召明
authored
|
105
|
await Task.Delay(1000);
|
唐召明
authored
|
106
|
var equipmentTemps = Equipments.Where(x => x.IP == item.IpAddress).ToList();
|
唐召明
authored
|
107
108
109
110
111
112
113
|
var props = equipmentTemps.SelectMany(x => x.EquipmentProps).Where(x => x.EquipmentTypePropTemplate.PropType != EquipmentPropType.Self).ToList();
if (props.Count == 0)
{
continue;
}
|
唐召明
authored
|
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
var temps = props.Select(x => new DataItem
{
Id = x.Id,
Code = x.EquipmentTypePropTemplateCode,
DataAddress = x.Address,
DataType = x.EquipmentTypePropTemplate.DataType,
Value = string.Empty
}).ToList();
//读取数据
var result = item.Read(temps);
if (!result.Success)
{
_log.LogError(result.Msg);
continue;
}
//赋值
foreach (var item in props)
{
item.Value = temps.Find(x => x.Id == item.Id).Value;
item.Updated = DateTime.Now;
}
|
唐召明
authored
|
136
|
|
唐召明
authored
|
137
|
foreach (var item in equipmentTemps)
|
唐召明
authored
|
138
|
{
|
唐召明
authored
|
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
var tags = item.EquipmentProps.Where(x =>
{
if (x.EquipmentTypePropTemplate.PropType == EquipmentPropType.PLCMonitorAddress
&& x.EquipmentTypePropTemplate.DataType == EquipmentDataType.BOOL)
{
//监控地址,只返回有报警的记录
return x.Value == bool.TrueString;
}
return true;
}).Select(x => new TagItem
{
Tag = x.EquipmentTypePropTemplateCode,
Value = x.Value
}).ToList();
|
唐召明
authored
|
154
|
var record = new EquipmentDataQueue
|
唐召明
authored
|
155
|
{
|
唐召明
authored
|
156
|
EquipmentCode = item.Code,
|
唐召明
authored
|
157
|
EquipmentName = item.Name,
|
唐召明
authored
|
158
159
|
EquipmentTypeCode = item.EquipmentType.Code,
IsCommit = false,
|
唐召明
authored
|
160
|
Reported = JsonSerializer.Serialize(tags),
|
唐召明
authored
|
161
|
Version = 1,
|
唐召明
authored
|
162
|
SourceTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
唐召明
authored
|
163
164
165
|
Created = DateTime.Now,
};
EquipmentDataQueues.Enqueue(record);
|
唐召明
authored
|
166
|
}
|
唐召明
authored
|
167
168
169
170
171
172
173
174
|
}
catch (Exception ex)
{
_log.LogError($"读取IP:{item.IpAddress}设备出现异常:{ex.Message}");
}
}
}, cts.Token);
}
|
唐召明
authored
|
175
|
_log.LogInfo($"程序已启动");
|
唐召明
authored
|
176
177
178
179
180
181
182
183
184
185
186
187
188
|
}
catch (Exception ex)
{
_log.LogException($"数据初始化失败:{ex.Message}");
}
}
/// <summary>
/// 停止PLC数据采集
/// </summary>
/// <returns></returns>
public void Stop()
{
|
唐召明
authored
|
189
|
Equipments.Clear();
|
唐召明
authored
|
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
|
_log.Log("已停止采集!");
cts.Cancel();//取消异步线程
}
private List<ICommunication> InitialCommunication(IEnumerable<CommunicationConfig> communicationConfigs)
{
var result = new List<ICommunication>();
try
{
foreach (var item in communicationConfigs)
{
ICommunication communication;
switch (item.CommunicationType)
{
case CommunicationTypeConst.None:
break;
case CommunicationTypeConst.KukaVarProxy:
communication = new KukaAvarProxyCommunication(item.Id, item.IpAddress, item.Port);
result.Add(communication);
break;
case CommunicationTypeConst.Siemens_S1200:
communication = new SiemensS7Communication(item.Id, SiemensPLCS.S1200, item.IpAddress);
result.Add(communication);
break;
case CommunicationTypeConst.Siemens_S1500:
communication = new SiemensS7Communication(item.Id, SiemensPLCS.S1500, item.IpAddress);
result.Add(communication);
break;
case CommunicationTypeConst.TcpClient:
communication = new TcpClientCommunication(item.Id, item.IpAddress, item.Port);
|
唐召明
authored
|
220
221
222
223
224
|
result.Add(communication);
break;
case CommunicationTypeConst.ModbusTcp:
communication = new ModbusTcpCommunication(item.Id, item.IpAddress, item.Port);
result.Add(communication);
|
唐召明
authored
|
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
break;
default:
break;
}
}
}
catch (Exception ex)
{
_log.LogError($"设备通讯初始化异常:{ex.Message}");
}
return result;
}
}
}
|