RTCommunicator_TLV.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. AlarmType = alarm.Value.AlarmType,
  108. HeaterType = heaterType,
  109. };
  110. try
  111. {
  112. this._provider?.ChannelAlarmNotify(alarmNotify);
  113. }
  114. catch
  115. {
  116. }
  117. break;
  118. case Tags.Mini8ConnectNotify:
  119. {
  120. byte index = data.RawData[0];
  121. this._DisconnectNotifyTimer.TryRemove(index, out Timer timer);
  122. timer?.Dispose();
  123. try
  124. {
  125. this._provider?.Mini8ConnectNotify(index);
  126. }
  127. catch
  128. {
  129. }
  130. break;
  131. }
  132. case Tags.Mini8DisconnectNotify:
  133. {
  134. byte index = data.RawData[0];
  135. if (!this._DisconnectNotifyTimer.ContainsKey(index))
  136. this._DisconnectNotifyTimer[index] = new(DisconnectNotifyTimerCallBack, index, 0, 1000);
  137. break;
  138. }
  139. case Tags.ChannelRealtimeDataNotify:
  140. if (!StructConverter.TryGetStruct(data.RawData, out ST_CHANNEL? channel) || channel is null)
  141. return;
  142. string key = $"{channel.Value.Mini8Index}-{channel.Value.ChannelIndex}";
  143. if (this.ChannelData.TryGetValue(key, out ST_CHANNEL_Notify notify) || notify is null)
  144. {
  145. notify = new()
  146. {
  147. Mini8Index = channel.Value.Mini8Index,
  148. ChannelIndex = channel.Value.ChannelIndex,
  149. PV = channel.Value.PV,
  150. Caps = channel.Value.Caps,
  151. Floor = channel.Value.Floor,
  152. };
  153. this.ChannelData[key] = notify;
  154. }
  155. else
  156. {
  157. notify.Mini8Index = channel.Value.Mini8Index;
  158. notify.ChannelIndex = channel.Value.ChannelIndex;
  159. notify.PV = channel.Value.PV;
  160. notify.Caps = channel.Value.Caps;
  161. notify.Floor = channel.Value.Floor;
  162. }
  163. try
  164. {
  165. this._provider?.ChannelRealtimeNotify(notify);
  166. }
  167. catch
  168. {
  169. }
  170. break;
  171. default:
  172. break;
  173. }
  174. });
  175. }
  176. TlvData ITlvProvider.RequestReply(TlvData tlvData)
  177. {
  178. return tlvData;
  179. }
  180. void ITlvProvider.Connected(TcpConnection connection)
  181. {
  182. this._provider.Connected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port);
  183. }
  184. void ITlvProvider.Disconnected(TcpConnection connection)
  185. {
  186. this._provider.DisConnected(connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port);
  187. }
  188. private void DisconnectNotifyTimerCallBack(object state)
  189. {
  190. if (state is not byte index)
  191. return;
  192. this._provider?.Mini8DisconnectNotify(index);
  193. }
  194. }