IOManager.cs 45 KB

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