RTCommunicator_TLV.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using RTCommunicatorBase;
  2. using System;
  3. using System.Collections.Concurrent;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. using TLVProtocal;
  10. using UniversalNetFrame451;
  11. using UniversalNetFrame451.IO;
  12. namespace RTCommunicatorTLV;
  13. public class RTCommunicator_TLV : IRTMini8Sender, ITlvProvider
  14. {
  15. private IRTMini8Provider _provider;
  16. private ITlvCommunicatorClient _client;
  17. private readonly ConcurrentDictionary<byte, Timer> _DisconnectNotifyTimer = [];
  18. private Dictionary<byte, Dictionary<byte, HeaterType>> _HeaterTypes;
  19. public ConcurrentDictionary<string, ST_CHANNEL_Notify> ChannelData { get; } = [];
  20. public bool Initialize(IRTMini8Provider provider)
  21. {
  22. if (provider is null)
  23. return false;
  24. if (this._provider is not null)
  25. return false;
  26. string path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "HeaterType.csv");
  27. if (!HeaterTypeAnalizer.Analize(path, out _HeaterTypes) || _HeaterTypes is null)
  28. return false;
  29. this._provider = provider;
  30. return true;
  31. }
  32. public bool StartService(string ip, int port)
  33. {
  34. if (_provider is null)
  35. return false;
  36. if (this._client is not null)
  37. return false;
  38. if (string.IsNullOrEmpty(ip) || port < 5000 || port > ushort.MaxValue)
  39. return false;
  40. ITlvCommunicatorClient client = TlvFactory.GetTlvClient();
  41. if (!client.Initialize(this, false, 500))
  42. return false;
  43. Task.Factory.StartNew(() =>
  44. {
  45. while (!client.Open(ip, (ushort)port))
  46. {
  47. Thread.Sleep(1000);
  48. }
  49. this._client = client;
  50. this._provider?.Connected(ip, port);
  51. });
  52. return true;
  53. }
  54. public bool CloseService()
  55. {
  56. this._client?.Dispose();
  57. this._client = null;
  58. this._provider = null;
  59. return true;
  60. }
  61. public bool SelectConfigFile(string name)
  62. {
  63. if (this._client is null)
  64. return false;
  65. if (string.IsNullOrEmpty(name))
  66. return false;
  67. byte[] bytes = Encoding.UTF8.GetBytes(name);
  68. TlvData data = new(1, bytes);
  69. return this._client?.SendNotify(data) == true;
  70. }
  71. void ITlvProvider.Received(TlvData data)
  72. {
  73. if (data.RawData is null || data.RawData.Length == 0)
  74. return;
  75. Task.Factory.StartNew(() =>
  76. {
  77. switch (data.Tag)
  78. {
  79. case Tags.CurrentTempConfigFile:
  80. string fileName = Encoding.UTF8.GetString(data.RawData);
  81. if (string.IsNullOrEmpty(fileName))
  82. return;
  83. try
  84. {
  85. this._provider?.CurrentTempConfigFile(fileName);
  86. }
  87. catch
  88. {
  89. }
  90. break;
  91. case Tags.ChannelAlarmNotify:
  92. if (!StructConverter.TryGetStruct(data.RawData, out ST_ALARM? alarm) || alarm is null)
  93. return;
  94. if (this._HeaterTypes is null)
  95. return;
  96. if (!this._HeaterTypes.TryGetValue(alarm.Value.Mini8Index, out var channels) || channels is null)
  97. return;
  98. if (!channels.TryGetValue(alarm.Value.ChannelIndex, out HeaterType heaterType))
  99. return;
  100. ST_ALARM_Notify alarmNotify = new()
  101. {
  102. Mini8Index = alarm.Value.Mini8Index,
  103. ChannelIndex = alarm.Value.ChannelIndex,
  104. PV = alarm.Value.PV,
  105. Caps = alarm.Value.Caps,
  106. Floor = alarm.Value.Floor,
  107. WorkingOutput = alarm.Value.WorkingOutput,
  108. AlarmType = alarm.Value.AlarmType,
  109. HeaterType = heaterType,
  110. };
  111. try
  112. {
  113. this._provider?.ChannelAlarmNotify(alarmNotify);
  114. }
  115. catch
  116. {
  117. }
  118. break;
  119. case Tags.Mini8ConnectNotify:
  120. {
  121. byte index = data.RawData[0];
  122. this._DisconnectNotifyTimer.TryRemove(index, out Timer timer);
  123. timer?.Dispose();
  124. try
  125. {
  126. this._provider?.Mini8ConnectNotify(index);
  127. }
  128. catch
  129. {
  130. }
  131. break;
  132. }
  133. case Tags.Mini8DisconnectNotify:
  134. {
  135. byte index = data.RawData[0];
  136. if (!this._DisconnectNotifyTimer.ContainsKey(index))
  137. this._DisconnectNotifyTimer[index] = new(DisconnectNotifyTimerCallBack, index, 0, 1000);
  138. break;
  139. }
  140. case Tags.ChannelRealtimeDataNotify:
  141. if (!StructConverter.TryGetStruct(data.RawData, out ST_CHANNEL? channel) || channel is null)
  142. return;
  143. string key = $"{channel.Value.Mini8Index}-{channel.Value.ChannelIndex}";
  144. if (this.ChannelData.TryGetValue(key, out ST_CHANNEL_Notify notify) || notify is null)
  145. {
  146. notify = new()
  147. {
  148. Mini8Index = channel.Value.Mini8Index,
  149. ChannelIndex = channel.Value.ChannelIndex,
  150. PV = channel.Value.PV,
  151. Caps = channel.Value.Caps,
  152. Floor = channel.Value.Floor,
  153. WorkingOutput = channel.Value.WorkingOutput,
  154. };
  155. this.ChannelData[key] = notify;
  156. }
  157. else
  158. {
  159. notify.Mini8Index = channel.Value.Mini8Index;
  160. notify.ChannelIndex = channel.Value.ChannelIndex;
  161. notify.PV = channel.Value.PV;
  162. notify.Caps = channel.Value.Caps;
  163. notify.Floor = channel.Value.Floor;
  164. notify.WorkingOutput = channel.Value.WorkingOutput;
  165. }
  166. try
  167. {
  168. this._provider?.ChannelRealtimeNotify(notify);
  169. }
  170. catch
  171. {
  172. }
  173. break;
  174. default:
  175. break;
  176. }
  177. });
  178. }
  179. TlvData ITlvProvider.RequestReply(TlvData tlvData)
  180. {
  181. return tlvData;
  182. }
  183. void ITlvProvider.Connected(TcpConnection connection)
  184. {
  185. this._provider.Connected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port);
  186. }
  187. void ITlvProvider.Disconnected(TcpConnection connection)
  188. {
  189. this._provider.DisConnected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port);
  190. }
  191. private void DisconnectNotifyTimerCallBack(object state)
  192. {
  193. if (state is not byte index)
  194. return;
  195. this._provider?.Mini8DisconnectNotify(index);
  196. }
  197. }