Blame view

HHECS.DAQClient/Services/CenterService.cs 10.9 KB
唐召明 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;
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
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;
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
            {
45
46
                if (string.IsNullOrWhiteSpace(currentArea))
                {
唐召明 authored
47
                    Equipments = _freeSql.Queryable<EquipmentExtend>().Where(x => !x.Disable).ToList();
48
49
50
                }
                else
                {
唐召明 authored
51
                    Equipments = _freeSql.Queryable<EquipmentExtend>().Where(x => !x.Disable && x.DestinationArea == currentArea).ToList();
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();
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))
81
                {
唐召明 authored
82
                    var equipmentIPAddressList = Equipments.Select(x => x.IP).ToList();
唐召明 authored
83
                    communicationConfigFliter = communicationConfigFliter.And(x => equipmentIPAddressList.Contains(x.IpAddress));
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
                            {
105
                                await Task.Delay(1000);
唐召明 authored
106
                                var equipmentTemps = Equipments.Where(x => x.IP == item.IpAddress).ToList();
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,
157
                                        EquipmentName = item.Name,
唐召明 authored
158
159
                                        EquipmentTypeCode = item.EquipmentType.Code,
                                        IsCommit = false,
唐召明 authored
160
                                        Reported = JsonSerializer.Serialize(tags),
唐召明 authored
161
                                        Version = 1,
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);
                }
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);
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;
        }
    }
}