DataCollectionSysyem.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. using Newtonsoft.Json;
  2. using PlcSiemens.Core.Extension;
  3. using ServiceCenter.Extensions;
  4. using ServiceCenter.Logs;
  5. using ServiceCenter.Redis;
  6. using ServiceCenter.SqlSugars;
  7. using System.Collections.Concurrent;
  8. using System.ComponentModel;
  9. using System.Data.SqlTypes;
  10. using System.Diagnostics;
  11. using System.Text;
  12. using WCS.Core;
  13. using WCS.Entity.Protocol.BCR;
  14. using WCS.Entity.Protocol.DataStructure;
  15. using WCS.Entity.Protocol.RGV;
  16. using WCS.Entity.Protocol.Robot;
  17. using WCS.Entity.Protocol.SRM;
  18. using WCS.Entity.Protocol.Station;
  19. using WCS.Entity.Protocol.Truss;
  20. using WCS.WorkEngineering.Extensions;
  21. using WCS.WorkEngineering.Worlds;
  22. namespace WCS.WorkEngineering.Systems
  23. {
  24. /// <summary>
  25. /// 数据采集
  26. /// </summary>
  27. [BelongTo(typeof(DataWorld))]
  28. [Description("数据采集系统")]
  29. public class DataCollectionSysyem : SystemBase
  30. {
  31. public static DeviceDataPack pack = new DeviceDataPack();
  32. private static object locker = new object();
  33. public DataCollectionSysyem()
  34. {
  35. var gs = Device.All.SelectMany(v => v.Protocols.Select(d => new { DB = $"{d.Value.DBInfo.No}:{d.Value.DBInfo.PLCInfo.IP}", d.Value.Position, TypeStr = d.Key, Dev = v }))
  36. .GroupBy(v => v.DB);
  37. foreach (var g in gs)
  38. {
  39. var min = g.OrderBy(v => v.Position).First();
  40. var max = g.OrderByDescending(v => v.Position).First();
  41. var t = Type.GetType(min.TypeStr);
  42. min.Dev.Protocol(t, this.World);
  43. max.Dev.Protocol(t, this.World);
  44. }
  45. }
  46. public override List<object> GetObjects()
  47. {
  48. return new List<object>();
  49. }
  50. public override void Update(List<WorkTimes> list)
  51. {
  52. try
  53. {
  54. var channel = new Channel
  55. {
  56. World = World.Description,
  57. Stage = "DoLogics",
  58. System = Description,
  59. Item = this.Description
  60. };
  61. Ltc.SetChannel(channel);
  62. var sw = new Stopwatch();
  63. sw.Start();
  64. #region 处理数据
  65. var sw1 = new Stopwatch();
  66. sw1.Start();
  67. var pack = new DeviceDataPack();
  68. var frame = DateTime.Now;
  69. pack.Frame = World.Frame;
  70. var ps = pack.GetType().GetProperties().OrderBy(x => x.Name);
  71. Parallel.ForEach(ps, p =>
  72. {
  73. if (!p.PropertyType.IsArray) return;
  74. var t = p.PropertyType.GetElementType();
  75. if (t.IsGenericType)
  76. {
  77. var entType = t.GetGenericArguments()[0];
  78. var protType = GetProtocolType(entType);
  79. if (protType == null) return;
  80. var devices = Device.All.Where(v => v.HasProtocol(protType));
  81. List<object> arr = new List<object>();
  82. Parallel.ForEach(devices, x =>
  83. {
  84. try
  85. {
  86. var protObj = x.Protocol(protType, World) as ProtocolProxyBase;
  87. if (protObj.Frame < DateTime.Now.AddYears(-24))
  88. {
  89. protObj.Frame = frame;
  90. }
  91. if (protObj.Db.Failed)
  92. {
  93. return;
  94. }
  95. var obj = Activator.CreateInstance(t);
  96. t.GetProperty("Code").SetValue(obj, x.Code);
  97. var value = WCS.Core.Extentions.Copy(protObj, entType, TimeZoneInfo.ConvertTimeToUtc(frame));
  98. t.GetProperty("Data").SetValue(obj, value);
  99. t.GetProperty("Frame").SetValue(obj, protObj.Frame);
  100. entType.GetProperty("Code").SetValue(value, x.Code);
  101. arr.Add(obj);
  102. }
  103. catch
  104. {
  105. }
  106. });
  107. var m = typeof(Enumerable).GetMethod("OfType",
  108. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
  109. m = m.MakeGenericMethod(t);
  110. var arr2 = m.Invoke(null, new object[] { arr });
  111. m = typeof(Enumerable).GetMethod("ToArray",
  112. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
  113. m = m.MakeGenericMethod(t);
  114. var arr3 = m.Invoke(null, new object[] { arr2 });
  115. p.SetValue(pack, arr3);
  116. }
  117. });
  118. sw1.Stop();
  119. #endregion 处理数据
  120. #region 存储监控数据
  121. var sw2 = new Stopwatch();
  122. sw2.Start();
  123. //开始存储设备信息
  124. RedisHub.Monitor.RPush("Packs", pack);
  125. if (RedisHub.Monitor.LLen("Packs") > 70000)
  126. {
  127. RedisHub.Monitor.LTrim("Packs", 5000, -1);
  128. }
  129. sw2.Stop();
  130. #endregion 存储监控数据
  131. #region 存储设备报警信息
  132. var sw3 = new Stopwatch();
  133. sw3.Start();
  134. List<EquipmentAlarm> equipmentAlarms = new List<EquipmentAlarm>();
  135. equipmentAlarms.AddRange(pack.Robot522.Where(x => x.Data.Alarm != 0).Select(x => new EquipmentAlarm()
  136. {
  137. Code = x.Code,
  138. Msg = x.Data.Alarm.ToString(),
  139. Time = x.Frame
  140. }));
  141. equipmentAlarms.AddRange(pack.SRM523.Where(x => x.Data.Alarm1 != 0 || x.Data.Alarm2 != 0).Select(x => new EquipmentAlarm()
  142. {
  143. Code = x.Code,
  144. Msg = $"{Convert.ToString(x.Data.Alarm1)},{Convert.ToString(x.Data.Alarm2)}",
  145. Time = x.Frame
  146. }));
  147. equipmentAlarms.AddRange(pack.Station523.Where(x => x.Data.Alarm != 0).Select(x => new EquipmentAlarm()
  148. {
  149. Code = x.Code,
  150. Msg = x.Data.Alarm.ToString(),
  151. Time = x.Frame
  152. }));
  153. equipmentAlarms.AddRange(pack.Truss523.Where(x => x.Data.Alarm != 0).Select(x => new EquipmentAlarm()
  154. {
  155. Code = x.Code,
  156. Msg = x.Data.Alarm.ToString(),
  157. Time = x.Frame
  158. }));
  159. RedisHub.Default.Set(nameof(EquipmentAlarm), JsonConvert.SerializeObject(equipmentAlarms));
  160. sw3.Stop();
  161. #endregion 存储设备报警信息
  162. #region 存储设备状态信息
  163. var sw4 = new Stopwatch();
  164. sw4.Start();
  165. List<EquipmentStatus> equipmentStatus = new List<EquipmentStatus>();
  166. equipmentStatus.AddRange(pack.RGV521.Where(x => x.Data.WorkMode != 0).Select(x => new EquipmentStatus()
  167. {
  168. Code = x.Code,
  169. con = x.Data.WorkMode.GetDescription(),
  170. Status = x.Data.WorkMode.ToInt(),
  171. Time = x.Frame
  172. }));
  173. equipmentStatus.AddRange(pack.Robot521.Where(x => x.Data.RobotMode != 0).Select(x => new EquipmentStatus()
  174. {
  175. Code = x.Code,
  176. con = x.Data.RobotMode.GetDescription(),
  177. Status = x.Data.RobotMode.ToInt(),
  178. Time = x.Frame
  179. }));
  180. equipmentStatus.AddRange(pack.SRM521.Where(x => x.Data.AutoStatus != 0).Select(x => new EquipmentStatus()
  181. {
  182. Code = x.Code,
  183. con = x.Data.AutoStatus.GetDescription(),
  184. Status = x.Data.AutoStatus.ToInt(),
  185. Time = x.Frame
  186. }));
  187. equipmentStatus.AddRange(pack.Station521.Where(x => x.Data.Mode != 0).Select(x => new EquipmentStatus()
  188. {
  189. Code = x.Code,
  190. con = x.Data.Mode.GetDescription(),
  191. Status = x.Data.Mode.ToInt(),
  192. Time = x.Frame
  193. }));
  194. equipmentStatus.AddRange(pack.Truss521.Where(x => x.Data.Status != 0).Select(x => new EquipmentStatus()
  195. {
  196. Code = x.Code,
  197. con = x.Data.Status.GetDescription(),
  198. Status = x.Data.Status.ToInt(),
  199. Time = x.Frame
  200. }));
  201. RedisHub.Default.Set(nameof(EquipmentStatus), JsonConvert.SerializeObject(equipmentStatus));
  202. sw4.Stop();
  203. #endregion 存储设备状态信息
  204. #region 存储数采数据
  205. var sw5 = new Stopwatch();
  206. sw5.Start();
  207. RedisHub.Monitor.RPush("DataCollectionpacks", pack);
  208. sw5.Stop();
  209. #endregion 存储数采数据
  210. sw.Stop();
  211. World.Log($"业务耗时:[{sw.ElapsedMilliseconds}]--处理数据:[{sw1.ElapsedMilliseconds}]--存储监控数据:[{sw2.ElapsedMilliseconds}]--存储设备报警信息:[{sw3.ElapsedMilliseconds}]--存储设备状态数据:[{sw4.ElapsedMilliseconds}]--存储数采数据:[{sw5.ElapsedMilliseconds}]");
  212. }
  213. catch (Exception e)
  214. {
  215. World.Log($"错误内容:{e.Message}");
  216. }
  217. }
  218. public void Set(StringBuilder sql, string cSql)
  219. {
  220. lock (locker)
  221. {
  222. sql.Append(cSql);
  223. }
  224. }
  225. private Type GetProtocolType(Type source)
  226. {
  227. var t = source.GetInterfaces().FirstOrDefault(v => v.GetInterfaces().Any(d => d.Name == "IProtocol"));
  228. var t1 = source.GetInterfaces().FirstOrDefault(v => v.GetInterfaces().Any(d => d.Name == "IProtocol"));
  229. return t;
  230. }
  231. private object AppendLock = new object();
  232. public StringBuilder Append(StringBuilder sql, string value)
  233. {
  234. lock (AppendLock)
  235. {
  236. return sql.Append(value);
  237. }
  238. }
  239. public string GetString(string value)
  240. {
  241. return value.Replace("INSERT INTO ", "")
  242. .Replace(",N'", ",'")
  243. .Replace("\0", "")
  244. .Replace("wcs_", "")
  245. .Replace("(N'", "('") + "\r";
  246. }
  247. }
  248. /// <summary>
  249. /// 设备报警
  250. /// </summary>
  251. public class EquipmentAlarm
  252. {
  253. /// <summary>
  254. /// 设备号
  255. /// </summary>
  256. public string Code { get; set; }
  257. /// <summary>
  258. /// 内容
  259. /// </summary>
  260. public string Msg { get; set; }
  261. /// <summary>
  262. /// 时间
  263. /// </summary>
  264. public DateTime Time { get; set; }
  265. }
  266. /// <summary>
  267. /// 设备状态信息
  268. /// </summary>
  269. public class EquipmentStatus
  270. {
  271. /// <summary>
  272. /// 设备号
  273. /// </summary>
  274. public string Code { get; set; }
  275. /// <summary>
  276. /// 内容
  277. /// </summary>
  278. public string con { get; set; }
  279. /// <summary>
  280. /// 内容
  281. /// </summary>
  282. public int Status { get; set; }
  283. /// <summary>
  284. /// 时间
  285. /// </summary>
  286. public DateTime Time { get; set; }
  287. }
  288. /// <summary>
  289. ///
  290. /// </summary>
  291. /// <typeparam name="T"></typeparam>
  292. public class Quest<T>
  293. {
  294. public T Data { get; set; }
  295. }
  296. }