IOGroupManager.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows.Forms.VisualStyles;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.RT.PLC;
  9. using Aitex.Core.Util;
  10. namespace Aitex.Core.RT.IOCore
  11. {
  12. public class IOGroupManager
  13. {
  14. public const int DioBlockLength = 200;
  15. public const int AioBlockLength = 200;
  16. private Dictionary<string, IO_DEFINE> _ioDefine = new Dictionary<string, IO_DEFINE>();
  17. private object _iomapLocker = new object();
  18. private Dictionary<string, object> _ioMap = new Dictionary<string, object>();
  19. private Dictionary<string, bool[]> _di = new Dictionary<string, bool[]>();
  20. private Dictionary<string, bool[]> _do = new Dictionary<string, bool[]>();
  21. private Dictionary<string, float[]> _ai = new Dictionary<string, float[]>();
  22. private Dictionary<string, float[]> _ao = new Dictionary<string, float[]>();
  23. private InterlockManager _interlock = new InterlockManager();
  24. private PeriodicJob _monitorThread;
  25. private Dictionary<string, int[]> _dicPlcIoBaseAddress = new Dictionary<string, int[]>();
  26. public void Initialize(Dictionary<string, string> ioDefineXmlFile, string interlockConfigFile, Dictionary<string, int[]> plcIoBaseAddress, List<string> logicDi)
  27. {
  28. _dicPlcIoBaseAddress = plcIoBaseAddress;
  29. try
  30. {
  31. foreach (var item in ioDefineXmlFile)
  32. {
  33. if (!File.Exists(item.Value))
  34. throw new Exception(string.Format("IO item define file not exist, {0}", item.Value));
  35. _ioDefine[item.Key] = CustomXmlSerializer.Deserialize<IO_DEFINE>(new FileInfo(item.Value));
  36. _di[item.Key] = new bool[DioBlockLength];
  37. _do[item.Key] = new bool[DioBlockLength];
  38. _ai[item.Key] = new float[AioBlockLength];
  39. _ao[item.Key] = new float[AioBlockLength];
  40. IOMapping(item.Key, plcIoBaseAddress[item.Key]);
  41. }
  42. }
  43. catch (Exception ex)
  44. {
  45. LOG.Write(ex);
  46. throw new Exception(string.Format("IO define file found error, \r\n {0}", ex.Message));
  47. }
  48. _di["logic"] = new bool[DioBlockLength];
  49. int index = 0;
  50. foreach (var diName in logicDi)
  51. {
  52. DIAccessor diAccessor = new DIAccessor(diName, index, _di["logic"], _di["logic"]);
  53. _ioMap[diName] = diAccessor;
  54. diAccessor.IoTableIndex = index;
  55. index++;
  56. }
  57. string reason = string.Empty;
  58. if (!_interlock.Initialize(interlockConfigFile, _ioMap, out reason))
  59. {
  60. throw new Exception(string.Format("interlock define file found error: \r\n {0}", reason));
  61. }
  62. _monitorThread = new PeriodicJob(200, OnTimer, "IO Monitor Thread", true);
  63. }
  64. private bool OnTimer()
  65. {
  66. try
  67. {
  68. _interlock.Monitor();
  69. }
  70. catch (Exception ex)
  71. {
  72. LOG.Write(ex);
  73. }
  74. return true;
  75. }
  76. public void Update<T, V>(string group, IDataBuffer<T, V> buf)
  77. where T : struct
  78. where V : struct
  79. {
  80. buf.UpdateDI(_di[group]);
  81. buf.UpdateDO(_do[group]);
  82. buf.UpdateAI(_ai[group]);
  83. buf.UpdateAO(_ao[group]);
  84. }
  85. public T GetIO<T>(string name) where T : class
  86. {
  87. T obj = null;
  88. lock (_iomapLocker)
  89. {
  90. if (_ioMap.ContainsKey(name))
  91. obj = _ioMap[name] as T;
  92. }
  93. if (obj == null)
  94. {
  95. if (!String.IsNullOrWhiteSpace(name))
  96. LOG.Error(string.Format("IO not match, can not find {0}", name));
  97. }
  98. return obj;
  99. }
  100. private void IOMapping(string group, int[] plcIoBaseAddress)
  101. {
  102. lock (_iomapLocker)
  103. {
  104. //DI
  105. foreach (DI_ITEM item in _ioDefine[group].Dig_In)
  106. {
  107. if (string.IsNullOrEmpty(item.Name))
  108. continue;
  109. int index = GetIndex(item.Addr, plcIoBaseAddress[0]);
  110. if (index > 200)
  111. {
  112. LOG.Write(String.Format("DI {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
  113. }
  114. if (index >= 0)
  115. {
  116. DIAccessor diAccessor = new DIAccessor(item.Name, index, _di[group], _di[group]);
  117. _ioMap[item.Name] = diAccessor;
  118. diAccessor.IoTableIndex = item.Index;
  119. //DATA.Subscribe(String.Format("IO.DI.{0}", item.Name), () => { return diAccessor.Value; });
  120. }
  121. else
  122. {
  123. LOG.Write(String.Format("DI{0} mapping error, addr is {1}", item.Index, item.Addr));
  124. }
  125. }
  126. //DO
  127. foreach (DO_ITEM item in _ioDefine[group].Dig_Out)
  128. {
  129. if (string.IsNullOrEmpty(item.Name))
  130. continue;
  131. int index = GetIndex(item.Addr, plcIoBaseAddress[1]);
  132. if (index > 200)
  133. {
  134. LOG.Write(String.Format("DO {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
  135. }
  136. if (index >= 0)
  137. {
  138. DOAccessor doAccessor = new DOAccessor(item.Name, index, _do[group]);
  139. _ioMap[item.Name] = doAccessor;
  140. doAccessor.IoTableIndex = item.Index;
  141. //DATA.Subscribe(String.Format("IO.DO.{0}", item.Name), () => { return doAccessor.Value; });
  142. }
  143. else
  144. {
  145. LOG.Write(String.Format("DO{0} mapping error, addr is {1}", item.Index, item.Addr));
  146. }
  147. }
  148. //AI
  149. foreach (AI_ITEM item in _ioDefine[group].Ana_In)
  150. {
  151. if (string.IsNullOrEmpty(item.Name))
  152. continue;
  153. int index = GetIndex(item.Addr, plcIoBaseAddress[2]);
  154. if (index > 200)
  155. {
  156. LOG.Write(String.Format("AI {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
  157. }
  158. if (index >= 0)
  159. {
  160. AIAccessor aiAccessor = new AIAccessor(item.Name, index, _ai[group]);
  161. _ioMap[item.Name] = aiAccessor;
  162. aiAccessor.IoTableIndex = item.Index;
  163. //DATA.Subscribe(String.Format("IO.AI.{0}", item.Name), () => { return aiAccessor.Value; });
  164. }
  165. else
  166. {
  167. LOG.Write(String.Format("AI{0} mapping error, addr is {1}", item.Index, item.Addr));
  168. }
  169. }
  170. //AO
  171. foreach (AO_ITEM item in _ioDefine[group].Ana_Out)
  172. {
  173. if (string.IsNullOrEmpty(item.Name))
  174. continue;
  175. int index = GetIndex(item.Addr, plcIoBaseAddress[3]);
  176. if (index > 200)
  177. {
  178. LOG.Write(String.Format("AO {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
  179. }
  180. if (index >= 0)
  181. {
  182. AOAccessor aoAccessor = new AOAccessor(item.Name, index, _ao[group]);
  183. _ioMap[item.Name] = aoAccessor;
  184. aoAccessor.IoTableIndex = item.Index;
  185. //DATA.Subscribe(String.Format("IO.AO.{0}", item.Name), () => { return aoAccessor.Value; });
  186. }
  187. else
  188. {
  189. LOG.Write(String.Format("AO{0} mapping error, addr is {1}", item.Index, item.Addr));
  190. }
  191. }
  192. }
  193. }
  194. private int GetIndex(string addr, int first)
  195. {
  196. if (String.IsNullOrEmpty(addr))
  197. {
  198. LOG.Write("GetIndex addr is empty");
  199. return -1;
  200. }
  201. string[] parts = addr.Trim().ToUpper().Split('.');
  202. int len = parts.Length;
  203. if (len == 1)
  204. {
  205. string ch = parts[0].TrimStart('D');
  206. int index = Convert.ToUInt16(ch);
  207. return (index - first) / 2;
  208. }
  209. if (len == 2)
  210. {
  211. char[] trim = { 'W', 'C', 'I', 'O', ' ' };
  212. string ch = parts[0].TrimStart(trim);
  213. int index = Convert.ToUInt16(ch);
  214. int bit = Convert.ToUInt16(parts[1]);
  215. return (index - first) * 16 + bit;
  216. }
  217. LOG.Info("IOManager GetIndex error");
  218. return -1;
  219. }
  220. public bool CanSetDo(string doName, bool onOff, out string reason)
  221. {
  222. return _interlock.CanSetDo(doName, onOff, out reason);
  223. }
  224. public List<Tuple<int, int, string>> GetIONameList(string group, IOType ioType)
  225. {
  226. List<Tuple<int, int, string>> result = new List<Tuple<int, int, string>>();
  227. if (!_dicPlcIoBaseAddress.ContainsKey(group))
  228. return result;
  229. int[] plcIoBaseAddress = _dicPlcIoBaseAddress[group];
  230. switch (ioType)
  231. {
  232. case IOType.AI:
  233. foreach (AI_ITEM item in _ioDefine[group].Ana_In)
  234. {
  235. if (string.IsNullOrEmpty(item.Name))
  236. continue;
  237. result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[2]), item.Name));
  238. }
  239. break;
  240. case IOType.AO:
  241. foreach (AO_ITEM item in _ioDefine[group].Ana_Out)
  242. {
  243. if (string.IsNullOrEmpty(item.Name))
  244. continue;
  245. result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[3]), item.Name));
  246. }
  247. break;
  248. case IOType.DI:
  249. foreach (DI_ITEM item in _ioDefine[group].Dig_In)
  250. {
  251. if (string.IsNullOrEmpty(item.Name))
  252. continue;
  253. result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[0]), item.Name));
  254. }
  255. break;
  256. case IOType.DO:
  257. foreach (DO_ITEM item in _ioDefine[group].Dig_Out)
  258. {
  259. if (string.IsNullOrEmpty(item.Name))
  260. continue;
  261. result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[1]), item.Name));
  262. }
  263. break;
  264. }
  265. return result;
  266. }
  267. public void Terminate()
  268. {
  269. try
  270. {
  271. _monitorThread.Stop();
  272. }
  273. catch (Exception ex)
  274. {
  275. LOG.Write(ex);
  276. }
  277. }
  278. }
  279. }