IOManager.cs 43 KB

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