终端一体化运控平台
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CommunicationServer.cs 13 KiB

2 년 전
2 년 전
2 년 전
2 년 전
2 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using BPASmart.Model;
  2. using BPA.Helper;
  3. using BPA.Communication;
  4. using Microsoft.EntityFrameworkCore.Metadata.Conventions;
  5. using Communication;
  6. using System.Collections.Concurrent;
  7. using Newtonsoft.Json;
  8. namespace BPASmart.Server
  9. {
  10. internal class CommunicationServer : IServer
  11. {
  12. ConcurrentDictionary<string, ICommunication> CommunicationDevices = new ConcurrentDictionary<string, ICommunication>();
  13. public void Init()
  14. {
  15. var tt = sizeof(bool);
  16. BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化");
  17. RedisHelper.GetInstance.ConnectAsync();
  18. MqttInit();
  19. Json<CommunicationPar>.Data.CommunicationDevices.ToList()?.ForEach(item =>
  20. {
  21. ThreadManage.GetInstance().Start(new Action(() =>
  22. {
  23. switch (item.CommDevice)
  24. {
  25. case BPASmart.Model.ModbusRtu _modbusRtu:
  26. break;
  27. case BPASmart.Model.ModbusTcp _modbusTcp:
  28. BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp();
  29. modbusTcpMaster.ConnectOk = new Action(() =>
  30. {
  31. if (!CommunicationDevices.ContainsKey(item.DeviceName))
  32. CommunicationDevices.TryAdd(item.DeviceName, modbusTcpMaster);
  33. ThreadManage.GetInstance().StartLong(new Action(() =>
  34. {
  35. GetReadDataModels(item).ToList()?.ForEach(temp =>
  36. {
  37. switch (temp.Key)
  38. {
  39. case EDataType.Bool:
  40. temp.Value?.ForEach(value =>
  41. {
  42. var res = modbusTcpMaster.ReadBool(value.StartAddress.ToString(), value.Length);
  43. SetValue(res.Content, item.DeviceName, value, 1);
  44. });
  45. break;
  46. case EDataType.Byte:
  47. break;
  48. case EDataType.Int:
  49. break;
  50. case EDataType.Word:
  51. temp.Value?.ForEach(value =>
  52. {
  53. var res = modbusTcpMaster.ReadUshort(value.StartAddress.ToString(), value.Length);
  54. SetValue(res.Content, item.DeviceName, value, 1);
  55. });
  56. break;
  57. case EDataType.Dint:
  58. break;
  59. case EDataType.Dword:
  60. temp.Value?.ForEach(value =>
  61. {
  62. var res = modbusTcpMaster.ReadUint(value.StartAddress.ToString(), value.Length);
  63. SetValue(res.Content, item.DeviceName, value, 2);
  64. });
  65. break;
  66. case EDataType.Float:
  67. temp.Value?.ForEach(value =>
  68. {
  69. var res = modbusTcpMaster.ReadFloat(value.StartAddress.ToString(), value.Length);
  70. SetValue(res.Content, item.DeviceName, value, 2);
  71. });
  72. break;
  73. default:
  74. break;
  75. }
  76. });
  77. Thread.Sleep(100);
  78. }), $"{item.DeviceName} 设备数据采集");
  79. var DeviceModel = item;
  80. });
  81. modbusTcpMaster.IsReconnect = true;
  82. modbusTcpMaster.ModbusTcpConnect(_modbusTcp.IP, _modbusTcp.PortNum);
  83. break;
  84. case BPASmart.Model.Siemens _siemens:
  85. break;
  86. default:
  87. break;
  88. }
  89. }), $"{item.DeviceName} 初始化连接");
  90. });
  91. }
  92. ConcurrentQueue<string> msg = new ConcurrentQueue<string>();
  93. private void MqttInit()
  94. {
  95. MqttHelper mqttHelper = new MqttHelper();
  96. mqttHelper.Connect("admin", "fengyoufu067101!@#", "124.222.238.75", 61613, $"分布式上位机:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
  97. mqttHelper.ConnectOk = new Action(() =>
  98. {
  99. mqttHelper.Subscrib("DistributedHostComputer/Control");
  100. ThreadManage.GetInstance().StartLong(new Action(() =>
  101. {
  102. while (msg.Count > 0)
  103. {
  104. DeviceControl();
  105. }
  106. Thread.Sleep(100);
  107. }), "MQTT 消息监听");
  108. });
  109. mqttHelper.MessageRecive = new Action<string>((s) =>
  110. {
  111. msg.Enqueue(s);
  112. });
  113. }
  114. private void DeviceControl()
  115. {
  116. if (msg.TryDequeue(out string s))
  117. {
  118. var res = JsonConvert.DeserializeObject<PublishInfo>(s);
  119. if (res != null)
  120. {
  121. res.PublishModels.ForEach(item =>
  122. {
  123. if (CommunicationDevices.ContainsKey(item.DeviceName))
  124. {
  125. switch (item.DataType)
  126. {
  127. case EDataType.Bool:
  128. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToBoolean(item.Value));
  129. break;
  130. case EDataType.Byte:
  131. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToByte(item.Value));
  132. break;
  133. case EDataType.Int:
  134. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToInt16(item.Value));
  135. break;
  136. case EDataType.Word:
  137. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToUInt16(item.Value));
  138. break;
  139. case EDataType.Dint:
  140. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToInt32(item.Value));
  141. break;
  142. case EDataType.Dword:
  143. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToUInt32(item.Value));
  144. break;
  145. case EDataType.Float:
  146. CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToSingle(item.Value));
  147. break;
  148. default:
  149. break;
  150. }
  151. }
  152. });
  153. }
  154. }
  155. }
  156. private void SetValue<TArray>(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by)
  157. {
  158. if (arrays != null)
  159. {
  160. int index = Array.FindIndex(Json<CommunicationPar>.Data.CommunicationDevices.ToArray(), p => p.DeviceName == DeviceName);//获取设备所在集合位置
  161. if (index >= 0 && index < Json<CommunicationPar>.Data.CommunicationDevices.Count)
  162. {
  163. var tempArray = Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ToArray();
  164. for (int i = 0; i < arrays.Length; i++)
  165. {
  166. int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == (readDataModel.StartAddress + (i * by)).ToString());
  167. if (varIndex >= 0 && varIndex < tempArray.Length)
  168. {
  169. Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays[i].ToString();
  170. }
  171. }
  172. var Devicename = Json<CommunicationPar>.Data.CommunicationDevices[index].DeviceName;
  173. List<ReeisDataModel> reeisDataModels = new List<ReeisDataModel>();
  174. Json<CommunicationPar>.Data.CommunicationDevices[index].VarTableModels.ToList().ForEach(tempVar =>
  175. {
  176. if (tempVar.VarName.Length > 0)
  177. {
  178. reeisDataModels.Add(new ReeisDataModel()
  179. {
  180. VarName = tempVar.VarName,
  181. VarVaule = tempVar.CurrentValue,
  182. DataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.DataType)
  183. });
  184. }
  185. });
  186. RedisHelper.GetInstance.SetValue($"{Devicename}", reeisDataModels);
  187. }
  188. }
  189. }
  190. private Dictionary<EDataType, List<ReadDataModel>> GetReadDataModels(CommunicationModel communicationModel)
  191. {
  192. Dictionary<EDataType, List<ReadDataModel>> readDataModels = new Dictionary<EDataType, List<ReadDataModel>>();
  193. communicationModel.VarTableModels.GroupBy(p => p.DataType)?.ToList()?.ForEach(tempVar =>
  194. {
  195. if (tempVar.Key != null && tempVar.Key.Length > 0)
  196. {
  197. //int address = tempVar.Min(p => p.RealAddress);
  198. EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key);
  199. switch (dataType)
  200. {
  201. case EDataType.Bool:
  202. case EDataType.Byte:
  203. case EDataType.Int:
  204. case EDataType.Word:
  205. if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar));
  206. break;
  207. case EDataType.Dint:
  208. case EDataType.Dword:
  209. case EDataType.Float:
  210. if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar, 2));
  211. break;
  212. default:
  213. break;
  214. }
  215. }
  216. });
  217. return readDataModels;
  218. }
  219. private List<ReadDataModel> GetDataGroup(IGrouping<string, VariableInfo> variableInfos, int by = 1)
  220. {
  221. List<ReadDataModel> ReturnValue = new List<ReadDataModel>();
  222. var res = variableInfos?.OrderBy(p => p.RealAddress).ToList();
  223. List<int> RealAddresss = new List<int>();
  224. variableInfos.ToList()?.ForEach(item => { if (int.TryParse(item.RealAddress, out int add)) RealAddresss.Add(add); });
  225. int count = 0;
  226. if (res != null)
  227. {
  228. //int address = variableInfos.Min(p => p.RealAddress);
  229. int address = RealAddresss.Min();
  230. int startAddress = address;
  231. for (int i = 0; i < res.Count; i++)
  232. {
  233. if (int.TryParse(res.ElementAt(i).RealAddress, out int TempAddress))
  234. {
  235. if (TempAddress == address)
  236. {
  237. count++;
  238. address += by;
  239. }
  240. else
  241. {
  242. ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count });
  243. count = 1;
  244. address = TempAddress + by;
  245. startAddress = TempAddress;
  246. }
  247. }
  248. }
  249. ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count });
  250. }
  251. return ReturnValue;
  252. }
  253. }
  254. }