IOManager.cs 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Xml;
  5. using Aitex.Core.Common.DeviceData;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Event;
  8. using Aitex.Core.RT.IOCore;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.Util;
  13. using MECF.Framework.RT.Core.IoProviders;
  14. namespace MECF.Framework.Common.IOCore
  15. {
  16. public class IoManager : Singleton<IoManager>, IIoBuffer
  17. {
  18. private Dictionary<string, DIAccessor> _diMap = new Dictionary<string, DIAccessor>();
  19. private Dictionary<string, DOAccessor> _doMap = new Dictionary<string, DOAccessor>();
  20. private Dictionary<string, AIAccessor> _aiMap = new Dictionary<string, AIAccessor>();
  21. private Dictionary<string, AOAccessor> _aoMap = new Dictionary<string, AOAccessor>();
  22. private Dictionary<string, Dictionary<int, bool[]>> _diBuffer = new Dictionary<string, Dictionary<int, bool[]>>();
  23. private Dictionary<string, Dictionary<int, bool[]>> _doBuffer = new Dictionary<string, Dictionary<int, bool[]>>();
  24. private Dictionary<string, Dictionary<int, short[]>> _aiBufferShort = new Dictionary<string, Dictionary<int, short[]>>();
  25. private Dictionary<string, Dictionary<int, short[]>> _aoBufferShort = new Dictionary<string, Dictionary<int, short[]>>();
  26. private Dictionary<string, Dictionary<int, float[]>> _aiBufferFloat = new Dictionary<string, Dictionary<int, float[]>>();
  27. private Dictionary<string, Dictionary<int, float[]>> _aoBufferFloat = new Dictionary<string, Dictionary<int, float[]>>();
  28. private Dictionary<string, Dictionary<int, Type>> _aiBufferType = new Dictionary<string, Dictionary<int, Type>>();
  29. private Dictionary<string, Dictionary<int, Type>> _aoBufferType = new Dictionary<string, Dictionary<int, Type>>();
  30. private Dictionary<string, List<DIAccessor>> _diList = new Dictionary<string, List<DIAccessor>>();
  31. private Dictionary<string, List<DOAccessor>> _doList = new Dictionary<string, List<DOAccessor>>();
  32. private Dictionary<string, List<AIAccessor>> _aiList = new Dictionary<string, List<AIAccessor>>();
  33. private Dictionary<string, List<AOAccessor>> _aoList = new Dictionary<string, List<AOAccessor>>();
  34. private Dictionary<string, List<NotifiableIoItem>> _ioItemList = new Dictionary<string, List<NotifiableIoItem>>();
  35. private PeriodicJob _monitorThread;
  36. /// <summary>
  37. /// 只有互锁用到
  38. /// </summary>
  39. /// <param name="interlockConfigFile"></param>
  40. public void Initialize(string interlockConfigFile, string interlockUserdefineConfigFile)
  41. {
  42. string reason = string.Empty;
  43. if (!string.IsNullOrEmpty(interlockConfigFile) && !InterlockManager.Instance.Initialize(interlockConfigFile, _doMap, _diMap, out reason))
  44. {
  45. throw new Exception(string.Format("interlock define file found error: \r\n {0}", reason));
  46. }
  47. if (!string.IsNullOrEmpty(interlockUserdefineConfigFile))
  48. {
  49. if (!InterlockManager.Instance.InitializeUserDefine(interlockUserdefineConfigFile, _doMap, _diMap, _aiMap, _aoMap, out reason))
  50. {
  51. throw new Exception(string.Format("interlock user define file found error: \r\n {0}", reason));
  52. }
  53. OP.Subscribe($"System.UpdateUserDefineInterlock", (string cmd, object[] args) =>
  54. {
  55. if (!InterlockManager.Instance.UpdateUserDefine(_doMap, _diMap, _aiMap, _aoMap, out reason))
  56. {
  57. throw new Exception(string.Format("interlock user define file found error: \r\n {0}", reason));
  58. }
  59. return true;
  60. });
  61. }
  62. _monitorThread = new PeriodicJob(200, OnTimer, "IO Monitor Thread", true);
  63. }
  64. private bool OnTimer()
  65. {
  66. try
  67. {
  68. InterlockManager.Instance.Monitor();
  69. }
  70. catch (Exception ex)
  71. {
  72. LOG.Write(ex);
  73. }
  74. return true;
  75. }
  76. internal List<Tuple<int, int, string>> GetIONameList(string group, IOType ioType)
  77. {
  78. return null;
  79. }
  80. public bool CanSetDo(string doName, bool onOff, out string reason)
  81. {
  82. return InterlockManager.Instance.CanSetDo(doName, onOff, out reason);
  83. }
  84. public List<DIAccessor> GetDIList(string source)
  85. {
  86. return _diList.ContainsKey(source) ? _diList[source] : null;
  87. }
  88. public List<DOAccessor> GetDOList(string source)
  89. {
  90. return _doList.ContainsKey(source) ? _doList[source] : null;
  91. }
  92. public List<AIAccessor> GetAIList(string source)
  93. {
  94. return _aiList.ContainsKey(source) ? _aiList[source] : null;
  95. }
  96. public List<AOAccessor> GetAOList(string source)
  97. {
  98. return _aoList.ContainsKey(source) ? _aoList[source] : null;
  99. }
  100. public IoManager()
  101. {
  102. OP.Subscribe("System.SetDoValue", InvokeSetDo);
  103. OP.Subscribe("System.SetAoValue", InvokeSetAo);
  104. OP.Subscribe("System.SetAoValueFloat", InvokeSetAoFloat);
  105. OP.Subscribe("System.SetDoValueWithPrivoder", InvokeSetDoWithPrivoder);
  106. OP.Subscribe("System.SetAoValueWithPrivoder", InvokeSetAoWithPrivoder);
  107. OP.Subscribe("System.SetAiBuffer", InvokeSetAiBuffer);
  108. OP.Subscribe("System.SetDiBuffer", InvokeSetDiBuffer);
  109. }
  110. private bool InvokeSetDo(string arg1, object[] args)
  111. {
  112. string name = (string)args[0];
  113. bool setpoint = (bool)args[1];
  114. string reason;
  115. if (!CanSetDo(name, setpoint, out reason))
  116. {
  117. if (Singleton<InterlockManager>.Instance.InterlockAlarms.ContainsKey(name))
  118. {
  119. Singleton<InterlockManager>.Instance.InterlockAlarms[name].Description = $"{reason}";
  120. Singleton<InterlockManager>.Instance.InterlockAlarms[name].Set();
  121. }
  122. else
  123. {
  124. EV.PostWarningLog("System", $"Can not set DO {name} to {setpoint}, {reason}");
  125. }
  126. DOAccessor do1 = GetIO<DOAccessor>(name);
  127. if (do1 == null)
  128. {
  129. EV.PostWarningLog("System", $"Can not set DO {name} to {setpoint}, not defined do");
  130. return false;
  131. }
  132. if (!do1.SetValue(setpoint, out reason,false))
  133. {
  134. EV.PostWarningLog("System", $"Can not set DO {name} to {setpoint}, {reason}");
  135. return false;
  136. }
  137. return false;
  138. }
  139. else
  140. {
  141. DOAccessor do1 = GetIO<DOAccessor>(name);
  142. if (do1 == null)
  143. {
  144. EV.PostWarningLog("System", $"Can not set DO {name} to {setpoint}, not defined do");
  145. return false;
  146. }
  147. if (!do1.SetValue(setpoint, out reason))
  148. {
  149. EV.PostWarningLog("System", $"Can not set DO {name} to {setpoint}, {reason}");
  150. return false;
  151. }
  152. EV.PostInfoLog("System", $"Change DO {name} to {setpoint}");
  153. }
  154. return true;
  155. }
  156. private bool InvokeSetAo(string arg1, object[] args)
  157. {
  158. string name = (string)args[0];
  159. short setpoint = (short)args[1];
  160. AOAccessor io = GetIO<AOAccessor>(name);
  161. if (io == null)
  162. {
  163. EV.PostWarningLog("System", $"Can not set AO {name} to {setpoint}, not defined do");
  164. return false;
  165. }
  166. io.Value = setpoint;
  167. EV.PostInfoLog("System", $"Change AO {name} to {setpoint}");
  168. return true;
  169. }
  170. private bool InvokeSetAoFloat(string arg1, object[] args)
  171. {
  172. string name = (string)args[0];
  173. float setpoint = (float)args[1];
  174. AOAccessor io = GetIO<AOAccessor>(name);
  175. if (io == null)
  176. {
  177. EV.PostWarningLog("System", $"Can not set AO {name} to {setpoint}, not defined");
  178. return false;
  179. }
  180. io.FloatValue = setpoint;
  181. EV.PostInfoLog("System", $"Change AO {name} to {setpoint}");
  182. return true;
  183. }
  184. private bool InvokeSetDoWithPrivoder(string arg1, object[] args)
  185. {
  186. string provider = (string)args[0];
  187. int offset = (int)args[1];
  188. string name = (string)args[2];
  189. bool setpoint = (bool)args[3];
  190. string reason;
  191. if (!CanSetDo(name, setpoint, out reason))
  192. {
  193. EV.PostWarningLog("System", $"Can not set DO {provider}.{name} to {setpoint}, {reason}");
  194. return false;
  195. }
  196. var doList = GetDOList(provider);
  197. if (doList == null)
  198. {
  199. EV.PostWarningLog("System", $"Can not set DO {provider}.{name} to {setpoint}, {reason}");
  200. return false;
  201. }
  202. var doAccessor = doList.FirstOrDefault(x => x.Name == name);
  203. if (doAccessor == default(DOAccessor))
  204. {
  205. EV.PostWarningLog("System", $"Can not set DO {provider}.{name} to {setpoint}, {reason}");
  206. return false;
  207. }
  208. if (!doAccessor.SetValue(setpoint, out reason))
  209. {
  210. EV.PostWarningLog("System", $"Can not set DO {provider}.{name} to {setpoint}, {reason}");
  211. return false;
  212. }
  213. EV.PostInfoLog("System", $"Change DO {provider}.{name} to {setpoint}");
  214. return true;
  215. }
  216. private bool InvokeSetAiBuffer(string arg1, object[] args)
  217. {
  218. string provider = (string)args[0];
  219. int offset = (int)args[1];
  220. short[] buffer = (short[])args[2];
  221. SetAiBuffer(provider, offset, buffer);
  222. return true;
  223. }
  224. private bool InvokeSetDiBuffer(string arg1, object[] args)
  225. {
  226. string provider = (string)args[0];
  227. int offset = (int)args[1];
  228. bool[] buffer = (bool[])args[2];
  229. SetDiBuffer(provider, offset, buffer);
  230. return true;
  231. }
  232. private bool InvokeSetAoWithPrivoder(string arg1, object[] args)
  233. {
  234. string provider = (string)args[0];
  235. int offset = (int)args[1];
  236. string name = (string)args[2];
  237. float setpoint = (float)args[3];
  238. string reason = "";
  239. var aoList = GetAOList(provider);
  240. if (aoList == null)
  241. {
  242. EV.PostWarningLog("System", $"Can not set AO {provider}.{name} to {setpoint}, {reason}");
  243. return false;
  244. }
  245. var aoAccessor = aoList.FirstOrDefault(x => x.Name == name);
  246. if (aoAccessor == default(AOAccessor))
  247. {
  248. EV.PostWarningLog("System", $"Can not set AO {provider}.{name} to {setpoint}, {reason}");
  249. return false;
  250. }
  251. aoAccessor.Value = (short)setpoint;
  252. EV.PostInfoLog("System", $"Change DO {provider}.{name} to {setpoint}");
  253. return true;
  254. }
  255. public T GetIO<T>(string name) where T : class
  256. {
  257. if (typeof(T) == typeof(DIAccessor) && _diMap.ContainsKey(name))
  258. {
  259. return _diMap[name] as T;
  260. }
  261. if (typeof(T) == typeof(DOAccessor) && _doMap.ContainsKey(name))
  262. {
  263. return _doMap[name] as T;
  264. }
  265. if (typeof(T) == typeof(AIAccessor) && _aiMap.ContainsKey(name))
  266. {
  267. return _aiMap[name] as T;
  268. }
  269. if (typeof(T) == typeof(AOAccessor) && _aoMap.ContainsKey(name))
  270. {
  271. return _aoMap[name] as T;
  272. }
  273. return null;
  274. }
  275. public Dictionary<int, bool[]> GetDiBuffer(string source)
  276. {
  277. if (_diBuffer.ContainsKey(source))
  278. {
  279. return _diBuffer[source];
  280. }
  281. return null;
  282. }
  283. public Dictionary<int, bool[]> GetDoBuffer(string source)
  284. {
  285. if (_doBuffer.ContainsKey(source))
  286. {
  287. return _doBuffer[source];
  288. }
  289. return null;
  290. }
  291. public Dictionary<int, short[]> GetAiBuffer(string source)
  292. {
  293. if (_aiBufferShort.ContainsKey(source))
  294. {
  295. return _aiBufferShort[source];
  296. }
  297. return null;
  298. }
  299. public Dictionary<int, float[]> GetAoBufferFloat(string source)
  300. {
  301. if (_aoBufferFloat.ContainsKey(source))
  302. {
  303. return _aoBufferFloat[source];
  304. }
  305. return null;
  306. }
  307. public Dictionary<int, float[]> GetAiBufferFloat(string source)
  308. {
  309. if (_aiBufferFloat.ContainsKey(source))
  310. {
  311. return _aiBufferFloat[source];
  312. }
  313. return null;
  314. }
  315. public Dictionary<int, short[]> GetAoBuffer(string source)
  316. {
  317. if (_aoBufferShort.ContainsKey(source))
  318. {
  319. return _aoBufferShort[source];
  320. }
  321. return null;
  322. }
  323. public void SetDiBuffer(string source, int offset, bool[] buffer)
  324. {
  325. if (_diBuffer.ContainsKey(source) && _diBuffer[source].ContainsKey(offset))
  326. {
  327. for (int i = 0; i < buffer.Length && i < _diBuffer[source][offset].Length; i++)
  328. {
  329. _diBuffer[source][offset][i] = buffer[i];
  330. }
  331. }
  332. }
  333. public void SetAiBuffer(string source, int offset, short[] buffer, int skipSize = 0)
  334. {
  335. if (_aiBufferShort.ContainsKey(source) && _aiBufferShort[source].ContainsKey(offset))
  336. {
  337. for (int i = 0; i < buffer.Length && i < _aiBufferShort[source][offset].Length; i++)
  338. {
  339. _aiBufferShort[source][offset][i + skipSize] = buffer[i];
  340. }
  341. }
  342. }
  343. public void SetAiBufferFloat(string source, int offset, float[] buffer, int skipSize = 0)
  344. {
  345. if (_aiBufferFloat.ContainsKey(source) && _aiBufferFloat[source].ContainsKey(offset))
  346. {
  347. for (int i = 0; i < buffer.Length && i < _aiBufferFloat[source][offset].Length; i++)
  348. {
  349. _aiBufferFloat[source][offset][i + skipSize] = buffer[i];
  350. }
  351. }
  352. }
  353. public void SetDoBuffer(string source, int offset, bool[] buffer)
  354. {
  355. if (_doBuffer.ContainsKey(source) && _doBuffer[source].ContainsKey(offset))
  356. {
  357. for (int i = 0; i < buffer.Length && i < _doBuffer[source][offset].Length; i++)
  358. {
  359. _doBuffer[source][offset][i] = buffer[i];
  360. }
  361. }
  362. }
  363. public void SetAoBuffer(string source, int offset, short[] buffer)
  364. {
  365. if (_aoBufferShort.ContainsKey(source) && _aoBufferShort[source].ContainsKey(offset))
  366. {
  367. for (int i = 0; i < buffer.Length && i < _aoBufferShort[source][offset].Length; i++)
  368. {
  369. _aoBufferShort[source][offset][i] = buffer[i];
  370. }
  371. }
  372. }
  373. public void SetAoBufferFloat(string source, int offset, float[] buffer, int bufferStartIndex = 0)
  374. {
  375. if (_aoBufferFloat.ContainsKey(source) && _aoBufferFloat[source].ContainsKey(offset))
  376. {
  377. for (int i = 0; i < buffer.Length && i < _aoBufferFloat[source][offset].Length; i++)
  378. {
  379. _aoBufferFloat[source][offset][i] = buffer[i];
  380. }
  381. }
  382. }
  383. //spin recipe set
  384. public void SetAoBuffer(string source, int offset, short[] buffer, int bufferStartIndex)
  385. {
  386. if (_aoBufferShort.ContainsKey(source) && _aoBufferShort[source].ContainsKey(offset) && _aoBufferShort[source][offset].Length > bufferStartIndex)
  387. {
  388. for (int i = 0; i < buffer.Length && bufferStartIndex + i < _aoBufferShort[source][offset].Length; i++)
  389. {
  390. _aoBufferShort[source][offset][bufferStartIndex + i] = buffer[i];
  391. }
  392. }
  393. }
  394. public void SetBufferBlock(string provider, List<IoBlockItem> lstBlocks)
  395. {
  396. foreach (var ioBlockItem in lstBlocks)
  397. {
  398. switch (ioBlockItem.Type)
  399. {
  400. case IoType.AI:
  401. if (!_aiBufferShort.ContainsKey(provider))
  402. {
  403. _aiBufferShort[provider] = new Dictionary<int, short[]>();
  404. _aiBufferFloat[provider] = new Dictionary<int, float[]>();
  405. _aiBufferType[provider] = new Dictionary<int, Type>();
  406. }
  407. if (!_aiBufferShort[provider].ContainsKey(ioBlockItem.Offset))
  408. {
  409. _aiBufferShort[provider][ioBlockItem.Offset] = new short[ioBlockItem.Size];
  410. _aiBufferFloat[provider][ioBlockItem.Offset] = new float[ioBlockItem.Size];
  411. _aiBufferType[provider][ioBlockItem.Offset] = ioBlockItem.AIOType;
  412. }
  413. break;
  414. case IoType.AO:
  415. if (!_aoBufferShort.ContainsKey(provider))
  416. {
  417. _aoBufferShort[provider] = new Dictionary<int, short[]>();
  418. _aoBufferFloat[provider] = new Dictionary<int, float[]>();
  419. _aoBufferType[provider] = new Dictionary<int, Type>();
  420. }
  421. if (!_aoBufferShort[provider].ContainsKey(ioBlockItem.Offset))
  422. {
  423. _aoBufferShort[provider][ioBlockItem.Offset] = new short[ioBlockItem.Size];
  424. _aoBufferFloat[provider][ioBlockItem.Offset] = new float[ioBlockItem.Size];
  425. _aoBufferType[provider][ioBlockItem.Offset] = ioBlockItem.AIOType;
  426. }
  427. break;
  428. case IoType.DI:
  429. if (!_diBuffer.ContainsKey(provider))
  430. {
  431. _diBuffer[provider] = new Dictionary<int, bool[]>();
  432. }
  433. if (!_diBuffer[provider].ContainsKey(ioBlockItem.Offset))
  434. {
  435. _diBuffer[provider][ioBlockItem.Offset] = new bool[ioBlockItem.Size];
  436. }
  437. break;
  438. case IoType.DO:
  439. if (!_doBuffer.ContainsKey(provider))
  440. {
  441. _doBuffer[provider] = new Dictionary<int, bool[]>();
  442. }
  443. if (!_doBuffer[provider].ContainsKey(ioBlockItem.Offset))
  444. {
  445. _doBuffer[provider][ioBlockItem.Offset] = new bool[ioBlockItem.Size];
  446. }
  447. break;
  448. }
  449. }
  450. }
  451. List<NotifiableIoItem> SubscribeDiData()
  452. {
  453. List<NotifiableIoItem> result = new List<NotifiableIoItem>();
  454. foreach (var ioDefine in _diMap)
  455. {
  456. NotifiableIoItem di = new NotifiableIoItem()
  457. {
  458. Address = ioDefine.Value.Addr,
  459. Name = ioDefine.Value.Name,
  460. Description = ioDefine.Value.Description,
  461. Index = ioDefine.Value.Index,
  462. BoolValue = ioDefine.Value.Value,
  463. Provider = ioDefine.Value.Provider,
  464. BlockOffset = ioDefine.Value.BlockOffset,
  465. BlockIndex = ioDefine.Value.Index,
  466. };
  467. result.Add(di);
  468. }
  469. return result;
  470. }
  471. List<NotifiableIoItem> SubscribeDoData()
  472. {
  473. List<NotifiableIoItem> result = new List<NotifiableIoItem>();
  474. foreach (var ioDefine in _doMap)
  475. {
  476. NotifiableIoItem io = new NotifiableIoItem()
  477. {
  478. Address = ioDefine.Value.Addr,
  479. Name = ioDefine.Value.Name,
  480. Description = ioDefine.Value.Description,
  481. Index = ioDefine.Value.Index,
  482. BoolValue = ioDefine.Value.Value,
  483. Provider = ioDefine.Value.Provider,
  484. BlockOffset = ioDefine.Value.BlockOffset,
  485. BlockIndex = ioDefine.Value.Index,
  486. };
  487. result.Add(io);
  488. }
  489. return result;
  490. }
  491. List<NotifiableIoItem> SubscribeAiData()
  492. {
  493. List<NotifiableIoItem> result = new List<NotifiableIoItem>();
  494. foreach (var ioDefine in _aiMap)
  495. {
  496. NotifiableIoItem di = new NotifiableIoItem()
  497. {
  498. Address = ioDefine.Value.Addr,
  499. Name = ioDefine.Value.Name,
  500. Description = ioDefine.Value.Description,
  501. Index = ioDefine.Value.Index,
  502. ShortValue = ioDefine.Value.Value,
  503. FloatValue = ioDefine.Value.FloatValue,
  504. Provider = ioDefine.Value.Provider,
  505. BlockOffset = ioDefine.Value.BlockOffset,
  506. BlockIndex = ioDefine.Value.Index,
  507. };
  508. result.Add(di);
  509. }
  510. return result;
  511. }
  512. List<NotifiableIoItem> SubscribeAoData()
  513. {
  514. List<NotifiableIoItem> result = new List<NotifiableIoItem>();
  515. foreach (var ioDefine in _aoMap)
  516. {
  517. NotifiableIoItem ao = new NotifiableIoItem()
  518. {
  519. Address = ioDefine.Value.Addr,
  520. Name = ioDefine.Value.Name,
  521. Description = ioDefine.Value.Description,
  522. Index = ioDefine.Value.Index,
  523. ShortValue = ioDefine.Value.Value,
  524. FloatValue = ioDefine.Value.FloatValue,
  525. Provider = ioDefine.Value.Provider,
  526. BlockOffset = ioDefine.Value.BlockOffset,
  527. BlockIndex = ioDefine.Value.Index,
  528. };
  529. result.Add(ao);
  530. }
  531. return result;
  532. }
  533. public void SetIoMap(string provider, int blockOffset, List<DIAccessor> ioList)
  534. {
  535. SubscribeIoItemList(provider);
  536. var scConfig = SC.GetConfigItem("System.IsIgnoreSaveDB");
  537. var isIgnoreSaveDB = scConfig != null && scConfig.BoolValue;
  538. foreach (var accessor in ioList)
  539. {
  540. accessor.Provider = provider;
  541. accessor.BlockOffset = blockOffset;
  542. _diMap[accessor.Name] = accessor;
  543. if (!_diList.ContainsKey(provider))
  544. _diList[provider] = new List<DIAccessor>();
  545. _diList[provider].Add(accessor);
  546. _ioItemList[$"{provider}.DIItemList"].Add(new NotifiableIoItem()
  547. {
  548. Address = accessor.Addr,
  549. Name = accessor.Name,
  550. Description = accessor.Description,
  551. Index = accessor.Index,
  552. Provider = provider,
  553. BlockOffset = blockOffset,
  554. BlockIndex = accessor.BlockOffset,
  555. });
  556. if (!isIgnoreSaveDB)
  557. DATA.Subscribe($"IO.{accessor.Name}", () => accessor.Value);
  558. }
  559. }
  560. public void SetIoMap(string provider, int blockOffset, List<DOAccessor> ioList)
  561. {
  562. SubscribeIoItemList(provider);
  563. var scConfig = SC.GetConfigItem("System.IsIgnoreSaveDB");
  564. var isIgnoreSaveDB = scConfig != null && scConfig.BoolValue;
  565. foreach (var accessor in ioList)
  566. {
  567. accessor.Provider = provider;
  568. accessor.BlockOffset = blockOffset;
  569. _doMap[accessor.Name] = accessor;
  570. if (!_doList.ContainsKey(provider))
  571. _doList[provider] = new List<DOAccessor>();
  572. _doList[provider].Add(accessor);
  573. _ioItemList[$"{provider}.DOItemList"].Add(new NotifiableIoItem()
  574. {
  575. Address = accessor.Addr,
  576. Name = accessor.Name,
  577. Description = accessor.Description,
  578. Index = accessor.Index,
  579. Provider = provider,
  580. BlockOffset = blockOffset,
  581. BlockIndex = accessor.BlockOffset,
  582. });
  583. if (!isIgnoreSaveDB)
  584. DATA.Subscribe($"IO.{accessor.Name}", () => accessor.Value);
  585. }
  586. }
  587. public void SetIoMap(string provider, int blockOffset, List<AIAccessor> ioList)
  588. {
  589. SubscribeIoItemList(provider);
  590. var scConfig = SC.GetConfigItem("System.IsIgnoreSaveDB");
  591. var isIgnoreSaveDB = scConfig != null && scConfig.BoolValue;
  592. foreach (var accessor in ioList)
  593. {
  594. accessor.Provider = provider;
  595. accessor.BlockOffset = blockOffset;
  596. _aiMap[accessor.Name] = accessor;
  597. if (!_aiList.ContainsKey(provider))
  598. _aiList[provider] = new List<AIAccessor>();
  599. _aiList[provider].Add(accessor);
  600. _ioItemList[$"{provider}.AIItemList"].Add(new NotifiableIoItem()
  601. {
  602. Address = accessor.Addr,
  603. Name = accessor.Name,
  604. Description = accessor.Description,
  605. Index = accessor.Index,
  606. Provider = provider,
  607. BlockOffset = blockOffset,
  608. BlockIndex = accessor.BlockOffset,
  609. });
  610. if (!isIgnoreSaveDB)
  611. DATA.Subscribe($"IO.{accessor.Name}", () => accessor.Value);
  612. }
  613. }
  614. public void SetIoMap(string provider, int blockOffset, List<AOAccessor> ioList)
  615. {
  616. SubscribeIoItemList(provider);
  617. var scConfig = SC.GetConfigItem("System.IsIgnoreSaveDB");
  618. var isIgnoreSaveDB = scConfig != null && scConfig.BoolValue;
  619. foreach (var accessor in ioList)
  620. {
  621. accessor.Provider = provider;
  622. accessor.BlockOffset = blockOffset;
  623. _aoMap[accessor.Name] = accessor;
  624. if (!_aoList.ContainsKey(provider))
  625. _aoList[provider] = new List<AOAccessor>();
  626. _aoList[provider].Add(accessor);
  627. _ioItemList[$"{provider}.AOItemList"].Add(new NotifiableIoItem()
  628. {
  629. Address = accessor.Addr,
  630. Name = accessor.Name,
  631. Description = accessor.Description,
  632. Index = accessor.Index,
  633. Provider = provider,
  634. BlockOffset = blockOffset,
  635. BlockIndex = accessor.BlockOffset,
  636. });
  637. if (!isIgnoreSaveDB)
  638. DATA.Subscribe($"IO.{accessor.Name}", () => accessor.Value);
  639. }
  640. }
  641. public void SetIoMap(string provider, int blockOffset, string xmlPathFile, string module = "")
  642. {
  643. SubscribeIoItemList(provider);
  644. XmlDocument xml = new XmlDocument();
  645. xml.Load(xmlPathFile);
  646. XmlNodeList lstDi = xml.SelectNodes("IO_DEFINE/Dig_In/DI_ITEM");
  647. var scConfig = SC.GetConfigItem("System.IsIgnoreSaveDB");
  648. var isIgnoreSaveDB = scConfig == null ? false : scConfig.BoolValue;
  649. //<DI_ITEM Index="0" Name="" BufferOffset="0" Addr="0" Description=""/>
  650. List<DIAccessor> diList = new List<DIAccessor>();
  651. foreach (var diItem in lstDi)
  652. {
  653. XmlElement element = diItem as XmlElement;
  654. if (element == null)
  655. continue;
  656. string index = element.GetAttribute("Index");
  657. string bufferOffset = element.GetAttribute("BufferOffset");
  658. if (string.IsNullOrEmpty(bufferOffset))
  659. bufferOffset = index;
  660. string name = element.GetAttribute("Name");
  661. string address = element.GetAttribute("Addr");
  662. string description = element.GetAttribute("Description");
  663. if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(index) || string.IsNullOrEmpty(bufferOffset))
  664. continue;
  665. name = name.Trim();
  666. index = index.Trim();
  667. bufferOffset = bufferOffset.Trim();
  668. string moduleName = string.IsNullOrEmpty(module) ? name : $"{module}.{name}";
  669. int intIndex;
  670. if (!int.TryParse(index, out intIndex))
  671. continue;
  672. int intBufferOffset;
  673. if (!int.TryParse(bufferOffset, out intBufferOffset))
  674. continue;
  675. if (!_diBuffer.ContainsKey(provider))
  676. {
  677. throw new Exception("Not defined DI buffer from IO provider, " + provider);
  678. }
  679. if (!_diBuffer[provider].ContainsKey(blockOffset))
  680. {
  681. throw new Exception("Not defined DI buffer from IO provider, " + provider);
  682. }
  683. DIAccessor diAccessor = new DIAccessor(moduleName, intBufferOffset, _diBuffer[provider][blockOffset], _diBuffer[provider][blockOffset]);
  684. diAccessor.IoTableIndex = intIndex;
  685. diAccessor.Addr = address;
  686. diAccessor.Provider = provider;
  687. diAccessor.BlockOffset = blockOffset;
  688. diAccessor.Description = description;
  689. diList.Add(diAccessor);
  690. _diMap[moduleName] = diAccessor;
  691. if (!_diList.ContainsKey(provider))
  692. _diList[provider] = new List<DIAccessor>();
  693. _diList[provider].Add(diAccessor);
  694. _ioItemList[$"{provider}.DIItemList"].Add(new NotifiableIoItem()
  695. {
  696. Address = address,
  697. Name = moduleName,
  698. Description = description,
  699. Index = intIndex,
  700. Provider = provider,
  701. BlockOffset = blockOffset,
  702. BlockIndex = intIndex,
  703. });
  704. if (!isIgnoreSaveDB)
  705. {
  706. DATA.Subscribe($"IO.{moduleName}", () => diAccessor.Value);
  707. }
  708. }
  709. XmlNodeList lstDo = xml.SelectNodes("IO_DEFINE/Dig_Out/DO_ITEM");
  710. // < DO_ITEM Index = "0" BufferOffset="0" Name = "" Addr = "0" Description = "" />
  711. foreach (var doItem in lstDo)
  712. {
  713. XmlElement element = doItem as XmlElement;
  714. if (element == null)
  715. continue;
  716. string index = element.GetAttribute("Index");
  717. string bufferOffset = element.GetAttribute("BufferOffset");
  718. if (string.IsNullOrEmpty(bufferOffset))
  719. bufferOffset = index;
  720. string name = element.GetAttribute("Name");
  721. string address = element.GetAttribute("Addr");
  722. string description = element.GetAttribute("Description");
  723. if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(index) || string.IsNullOrEmpty(bufferOffset))
  724. continue;
  725. name = name.Trim();
  726. index = index.Trim();
  727. bufferOffset = bufferOffset.Trim();
  728. string moduleName = string.IsNullOrEmpty(module) ? name : $"{module}.{name}";
  729. int intIndex;
  730. if (!int.TryParse(index, out intIndex))
  731. continue;
  732. int intBufferOffset;
  733. if (!int.TryParse(bufferOffset, out intBufferOffset))
  734. continue;
  735. if (!_doBuffer.ContainsKey(provider) || !_doBuffer[provider].ContainsKey(blockOffset))
  736. {
  737. throw new Exception("Not defined DO buffer from IO provider, " + provider);
  738. }
  739. DOAccessor doAccessor = new DOAccessor(moduleName, intBufferOffset, _doBuffer[provider][blockOffset]);
  740. _doMap[moduleName] = doAccessor;
  741. doAccessor.IoTableIndex = intIndex;
  742. doAccessor.Addr = address;
  743. doAccessor.Provider = provider;
  744. doAccessor.BlockOffset = blockOffset;
  745. doAccessor.Description = description;
  746. if (!_doList.ContainsKey(provider))
  747. _doList[provider] = new List<DOAccessor>();
  748. _doList[provider].Add(doAccessor);
  749. _ioItemList[$"{provider}.DOItemList"].Add(new NotifiableIoItem()
  750. {
  751. Address = address,
  752. Name = moduleName,
  753. Description = description,
  754. Index = intIndex,
  755. Provider = provider,
  756. BlockOffset = blockOffset,
  757. BlockIndex = intIndex,
  758. });
  759. if (!isIgnoreSaveDB)
  760. DATA.Subscribe($"IO.{moduleName}", () => doAccessor.Value);
  761. }
  762. XmlNodeList lstAo = xml.SelectNodes("IO_DEFINE/Ana_Out/AO_ITEM");
  763. // < AO_ITEM Index = "0" BufferOffset="0" Name = "" Addr = "0" Description = "" />
  764. foreach (var aoItem in lstAo)
  765. {
  766. XmlElement element = aoItem as XmlElement;
  767. if (element == null)
  768. continue;
  769. string index = element.GetAttribute("Index");
  770. string bufferOffset = element.GetAttribute("BufferOffset");
  771. if (string.IsNullOrEmpty(bufferOffset))
  772. bufferOffset = index;
  773. string name = element.GetAttribute("Name");
  774. string address = element.GetAttribute("Addr");
  775. string description = element.GetAttribute("Description");
  776. if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(index) || string.IsNullOrEmpty(bufferOffset))
  777. continue;
  778. name = name.Trim();
  779. index = index.Trim();
  780. bufferOffset = bufferOffset.Trim();
  781. string moduleName = string.IsNullOrEmpty(module) ? name : $"{module}.{name}";
  782. int intIndex;
  783. if (!int.TryParse(index, out intIndex))
  784. continue;
  785. int intBufferOffset;
  786. if (!int.TryParse(bufferOffset, out intBufferOffset))
  787. continue;
  788. if (!_aoBufferShort.ContainsKey(provider) || !_aoBufferShort[provider].ContainsKey(blockOffset))
  789. {
  790. throw new Exception("Not defined AO buffer from IO provider, " + provider);
  791. }
  792. AOAccessor aoAccessor = new AOAccessor(moduleName, intBufferOffset, _aoBufferShort[provider][blockOffset], _aoBufferFloat[provider][blockOffset]);
  793. _aoMap[moduleName] = aoAccessor;
  794. aoAccessor.IoTableIndex = intIndex;
  795. aoAccessor.Addr = address;
  796. aoAccessor.Provider = provider;
  797. aoAccessor.BlockOffset = blockOffset;
  798. aoAccessor.Description = description;
  799. if (!_aoList.ContainsKey(provider))
  800. _aoList[provider] = new List<AOAccessor>();
  801. _aoList[provider].Add(aoAccessor);
  802. _ioItemList[$"{provider}.AOItemList"].Add(new NotifiableIoItem()
  803. {
  804. Address = address,
  805. Name = moduleName,
  806. Description = description,
  807. Index = intIndex,
  808. Provider = provider,
  809. BlockOffset = blockOffset,
  810. BlockIndex = intIndex,
  811. });
  812. if (!isIgnoreSaveDB)
  813. {
  814. if (_aoBufferType.ContainsKey(provider) && _aoBufferType[provider].ContainsKey(blockOffset) &&
  815. _aoBufferType[provider][blockOffset] == typeof(float))
  816. {
  817. DATA.Subscribe($"IO.{moduleName}", () => aoAccessor.FloatValue);
  818. }
  819. else
  820. {
  821. DATA.Subscribe($"IO.{moduleName}", () => aoAccessor.Value);
  822. }
  823. }
  824. }
  825. XmlNodeList lstAi = xml.SelectNodes("IO_DEFINE/Ana_In/AI_ITEM");
  826. // < AO_ITEM Index = "0" BufferOffset="0" Name = "" Addr = "0" Description = "" />
  827. foreach (var aiItem in lstAi)
  828. {
  829. XmlElement element = aiItem as XmlElement;
  830. if (element == null)
  831. continue;
  832. string index = element.GetAttribute("Index");
  833. string bufferOffset = element.GetAttribute("BufferOffset");
  834. if (string.IsNullOrEmpty(bufferOffset))
  835. bufferOffset = index;
  836. string name = element.GetAttribute("Name");
  837. string address = element.GetAttribute("Addr");
  838. string description = element.GetAttribute("Description");
  839. if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(index) || string.IsNullOrEmpty(bufferOffset))
  840. continue;
  841. name = name.Trim();
  842. index = index.Trim();
  843. bufferOffset = bufferOffset.Trim();
  844. string nameWithModule = string.IsNullOrEmpty(module) ? name : $"{module}.{name}";
  845. int intIndex;
  846. if (!int.TryParse(index, out intIndex))
  847. continue;
  848. int intBufferOffset;
  849. if (!int.TryParse(bufferOffset, out intBufferOffset))
  850. continue;
  851. if (!_aiBufferShort.ContainsKey(provider) || !_aiBufferShort[provider].ContainsKey(blockOffset))
  852. {
  853. throw new Exception("Not defined AI buffer from IO provider, " + provider);
  854. }
  855. AIAccessor aiAccessor = new AIAccessor(nameWithModule, intBufferOffset, _aiBufferShort[provider][blockOffset], _aiBufferFloat[provider][blockOffset]);
  856. _aiMap[nameWithModule] = aiAccessor;
  857. aiAccessor.IoTableIndex = intIndex;
  858. aiAccessor.Addr = address;
  859. aiAccessor.Provider = provider;
  860. aiAccessor.BlockOffset = blockOffset;
  861. aiAccessor.Description = description;
  862. if (!_aiList.ContainsKey(provider))
  863. _aiList[provider] = new List<AIAccessor>();
  864. _aiList[provider].Add(aiAccessor);
  865. _ioItemList[$"{provider}.AIItemList"].Add(new NotifiableIoItem()
  866. {
  867. Address = address,
  868. Name = nameWithModule,
  869. Description = description,
  870. Index = intIndex,
  871. Provider = provider,
  872. BlockOffset = blockOffset,
  873. BlockIndex = intIndex,
  874. });
  875. if (!isIgnoreSaveDB)
  876. {
  877. if (_aiBufferType.ContainsKey(provider) && _aiBufferType[provider].ContainsKey(blockOffset) &&
  878. _aiBufferType[provider][blockOffset] == typeof(float))
  879. {
  880. DATA.Subscribe($"IO.{nameWithModule}", () => aiAccessor.FloatValue);
  881. }
  882. else
  883. {
  884. DATA.Subscribe($"IO.{nameWithModule}", () => aiAccessor.Value);
  885. }
  886. }
  887. }
  888. }
  889. public void SetIoMap(string provider, Dictionary<int, string> ioMappingPathFile)
  890. {
  891. foreach (var map in ioMappingPathFile)
  892. {
  893. SetIoMap(provider, map.Key, map.Value);
  894. }
  895. DATA.Subscribe(provider, "DIList", SubscribeDiData);
  896. DATA.Subscribe(provider, "DOList", SubscribeDoData);
  897. DATA.Subscribe(provider, "AIList", SubscribeAiData);
  898. DATA.Subscribe(provider, "AOList", SubscribeAoData);
  899. }
  900. public void SetIoMapByModule(string provider, int offset, string ioMappingPathFile, string module)
  901. {
  902. SetIoMap(provider, offset, ioMappingPathFile, module);
  903. DATA.Subscribe(provider, "DIList", SubscribeDiData);
  904. DATA.Subscribe(provider, "DOList", SubscribeDoData);
  905. DATA.Subscribe(provider, "AIList", SubscribeAiData);
  906. DATA.Subscribe(provider, "AOList", SubscribeAoData);
  907. }
  908. private void SubscribeIoItemList(string provider)
  909. {
  910. string diKey = $"{provider}.DIItemList";
  911. if (!_ioItemList.ContainsKey(diKey))
  912. {
  913. _ioItemList[diKey] = new List<NotifiableIoItem>();
  914. DATA.Subscribe(diKey, () => _ioItemList[diKey]);
  915. }
  916. string doKey = $"{provider}.DOItemList";
  917. if (!_ioItemList.ContainsKey(doKey))
  918. {
  919. _ioItemList[doKey] = new List<NotifiableIoItem>();
  920. DATA.Subscribe(doKey, () => _ioItemList[doKey]);
  921. }
  922. string aiKey = $"{provider}.AIItemList";
  923. if (!_ioItemList.ContainsKey(aiKey))
  924. {
  925. _ioItemList[aiKey] = new List<NotifiableIoItem>();
  926. DATA.Subscribe(aiKey, () => _ioItemList[aiKey]);
  927. }
  928. string aoKey = $"{provider}.AOItemList";
  929. if (!_ioItemList.ContainsKey(aoKey))
  930. {
  931. _ioItemList[aoKey] = new List<NotifiableIoItem>();
  932. DATA.Subscribe(aoKey, () => _ioItemList[aoKey]);
  933. }
  934. }
  935. }
  936. }