IoProvider.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Xml;
  7. using Aitex.Core.RT.DataCenter;
  8. using Aitex.Core.RT.Event;
  9. using Aitex.Core.RT.IOCore;
  10. using Aitex.Core.RT.Log;
  11. using Aitex.Core.Util;
  12. using MECF.Framework.Common.Event;
  13. namespace MECF.Framework.RT.Core.IoProviders
  14. {
  15. public abstract class IoProvider : IIoProvider, IAlarmHandler
  16. {
  17. public string Module { get; set; }
  18. public string Name { get; set; }
  19. public bool IsOpened
  20. {
  21. get { return State == IoProviderStateEnum.Opened; }
  22. }
  23. public IoProviderStateEnum State { get; set; }
  24. public virtual AlarmEventItem DisconnectAlarm { get; set; }
  25. public virtual AlarmEventItem CommunicationErrorAlarm { get; set; }
  26. public event Action<string, AlarmEventItem> OnDeviceAlarmStateChanged;
  27. protected PeriodicJob _thread;
  28. protected IIoBuffer _buffer;
  29. protected R_TRIG _trigError = new R_TRIG();
  30. protected RD_TRIG _trigNotConnected = new RD_TRIG();
  31. protected string _source;
  32. protected XmlElement _nodeParameter;
  33. protected List<IoBlockItem> _blockSections;
  34. protected abstract void SetParameter(XmlElement nodeParameter);
  35. protected abstract void Open();
  36. protected abstract void Close();
  37. protected abstract bool[] ReadDi(int offset, int size);
  38. protected abstract short[] ReadAi(int offset, int size);
  39. protected abstract void WriteDo(int offset, bool[] buffer);
  40. protected abstract void WriteAo(int offset, short[] buffer);
  41. protected virtual float[] ReadAiFloat(int offset, int size)
  42. {
  43. return null;
  44. }
  45. protected virtual void WriteAoFloat(int offset, float[] buffer)
  46. {
  47. }
  48. /// <summary>
  49. /// 单腔体
  50. /// </summary>
  51. /// <param name="module"></param>
  52. /// <param name="name"></param>
  53. /// <param name="lstBuffers"></param>
  54. /// <param name="buffer"></param>
  55. /// <param name="nodeParameter"></param>
  56. /// <param name="ioMappingPathFile"></param>
  57. public virtual void Initialize(string module, string name,List<IoBlockItem> lstBuffers , IIoBuffer buffer, XmlElement nodeParameter, Dictionary<int, string> ioMappingPathFile)
  58. {
  59. Module = module;
  60. Name = name;
  61. _source = module + "." + name;
  62. _buffer = buffer;
  63. _nodeParameter = nodeParameter;
  64. _blockSections = lstBuffers;
  65. buffer.SetBufferBlock(_source, lstBuffers);
  66. buffer.SetIoMap(_source, ioMappingPathFile);
  67. SetParameter(nodeParameter);
  68. State = IoProviderStateEnum.Uninitialized;
  69. _thread = new PeriodicJob(50, OnTimer, name);
  70. }
  71. /// <summary>
  72. /// 多腔体
  73. /// </summary>
  74. /// <param name="module"></param>
  75. /// <param name="name"></param>
  76. /// <param name="lstBuffers"></param>
  77. /// <param name="buffer"></param>
  78. /// <param name="nodeParameter"></param>
  79. /// <param name="ioMappingPathFile"></param>
  80. /// <param name="ioModule"></param>
  81. public virtual void Initialize(string module, string name, List<IoBlockItem> lstBuffers, IIoBuffer buffer, XmlElement nodeParameter, string ioMappingPathFile, string ioModule )
  82. {
  83. Module = module;
  84. Name = name;
  85. _source = module + "." + name;
  86. _buffer = buffer;
  87. _nodeParameter = nodeParameter;
  88. _blockSections = lstBuffers;
  89. buffer.SetBufferBlock(_source, lstBuffers);
  90. buffer.SetIoMapByModule(_source, 0, ioMappingPathFile, ioModule);
  91. SetParameter(nodeParameter);
  92. State = IoProviderStateEnum.Uninitialized;
  93. _thread = new PeriodicJob(50, OnTimer, name);
  94. }
  95. protected void SetState(IoProviderStateEnum newState)
  96. {
  97. State = newState;
  98. }
  99. public void TraceArray(bool[] data)
  100. {
  101. string[] values = new string[data.Length];
  102. for (int i = 0; i < data.Length; i++)
  103. {
  104. values[i++] = data[i] ? "1" : "0";
  105. }
  106. System.Diagnostics.Trace.WriteLine(string.Join(",", values));
  107. }
  108. protected virtual bool OnTimer()
  109. {
  110. if (State == IoProviderStateEnum.Uninitialized)
  111. {
  112. SetState(IoProviderStateEnum.Opening);
  113. Open();
  114. }
  115. if (State == IoProviderStateEnum.Opened)
  116. {
  117. try
  118. {
  119. bool isAIOFloatType = false;
  120. foreach (var bufferSection in _blockSections)
  121. {
  122. if (bufferSection.Type == IoType.DI)
  123. {
  124. bool[] diBuffer = ReadDi(bufferSection.Offset, bufferSection.Size);
  125. if (diBuffer != null)
  126. {
  127. _buffer.SetDiBuffer(_source, bufferSection.Offset, diBuffer);
  128. //TraceArray(diBuffer);
  129. }
  130. }
  131. else if (bufferSection.Type == IoType.AI)
  132. {
  133. short[] aiBuffer = ReadAi(bufferSection.Offset, bufferSection.Size);
  134. if (aiBuffer != null)
  135. {
  136. _buffer.SetAiBuffer(_source, bufferSection.Offset, aiBuffer);
  137. if (bufferSection.AIOType == typeof(float))
  138. {
  139. isAIOFloatType = true;
  140. _buffer.SetAiBufferFloat(_source, bufferSection.Offset, Array.ConvertAll(aiBuffer, x => (float)x).ToArray());
  141. }
  142. }
  143. }
  144. }
  145. Dictionary<int, short[]> aos = _buffer.GetAoBuffer(_source);
  146. if (aos != null)
  147. {
  148. foreach (var ao in aos)
  149. {
  150. WriteAo(ao.Key, ao.Value);
  151. if (isAIOFloatType)
  152. WriteAoFloat(ao.Key, Array.ConvertAll(ao.Value, x => (float)x).ToArray());
  153. }
  154. }
  155. Dictionary<int, bool[]> dos = _buffer.GetDoBuffer(_source);
  156. if (dos != null)
  157. {
  158. foreach (var doo in dos)
  159. {
  160. WriteDo(doo.Key, doo.Value);
  161. }
  162. }
  163. }
  164. catch (Exception ex)
  165. {
  166. LOG.Write(ex);
  167. SetState(IoProviderStateEnum.Error);
  168. Close();
  169. }
  170. }
  171. _trigError.CLK = State == IoProviderStateEnum.Error;
  172. if (_trigError.Q)
  173. {
  174. EV.PostAlarmLog(Module, $"{_source} error");
  175. }
  176. _trigNotConnected.CLK = State != IoProviderStateEnum.Opened;
  177. if (_trigNotConnected.T)
  178. {
  179. EV.PostInfoLog(Module, $"{_source} connected");
  180. }
  181. if (_trigNotConnected.R)
  182. {
  183. EV.PostWarningLog(Module, $"{_source} not connected");
  184. }
  185. return true;
  186. }
  187. public virtual bool ResetAlarm()
  188. {
  189. return true;
  190. }
  191. public virtual void Reset()
  192. {
  193. _trigError.RST = true;
  194. _trigNotConnected.RST = true;
  195. }
  196. public void Start()
  197. {
  198. if(_thread != null)
  199. _thread.Start();
  200. }
  201. public void Stop()
  202. {
  203. SetState(IoProviderStateEnum.Closing);
  204. Close();
  205. _thread.Stop();
  206. }
  207. public virtual bool SetValue(AOAccessor aoItem, short value)
  208. {
  209. return true;
  210. }
  211. public virtual bool SetValueFloat(AOAccessor aoItem, float value)
  212. {
  213. return true;
  214. }
  215. public virtual bool SetValue(DOAccessor doItem, bool value)
  216. {
  217. return true;
  218. }
  219. protected AlarmEventItem SubscribeAlarm(string name, string description, Func<bool> resetChecker, EventLevel level = EventLevel.Alarm)
  220. {
  221. AlarmEventItem item = new AlarmEventItem(Module, name, description, resetChecker, this);
  222. item.Level = level;
  223. EV.Subscribe(item);
  224. return item;
  225. }
  226. public void AlarmStateChanged(AlarmEventItem args)
  227. {
  228. if (OnDeviceAlarmStateChanged != null)
  229. {
  230. OnDeviceAlarmStateChanged($"{Module}.{Name}", args);
  231. }
  232. }
  233. }
  234. }