UIViewModelBase.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.UI.MVVM;
  4. using Aitex.Core.Util;
  5. using Aitex.Core.Utilities;
  6. using Caliburn.Micro.Core;
  7. using MECF.Framework.Common.DataCenter;
  8. using MECF.Framework.Common.IOCore;
  9. using MECF.Framework.Common.Utilities;
  10. using OpenSEMI.Ctrlib.Controls;
  11. using System;
  12. using System.Collections.Concurrent;
  13. using System.Collections.Generic;
  14. using System.Collections.ObjectModel;
  15. using System.Linq;
  16. using System.Reflection;
  17. using System.Threading.Tasks;
  18. using System.Windows;
  19. using System.Windows.Controls;
  20. using System.Windows.Input;
  21. using System.Xml.Linq;
  22. namespace MECF.Framework.UI.Client.ClientBase
  23. {
  24. public class ModuleUiViewModelBase : UiViewModelBase
  25. {
  26. public string SystemName { get; set; }
  27. public override void SubscribeKeys()
  28. {
  29. SubscribeKeys(this, SystemName);
  30. }
  31. public override void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  32. {
  33. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  34. property =>
  35. {
  36. PropertyInfo pi = (PropertyInfo)property;
  37. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  38. string key = subscription.ModuleKey;
  39. key = module == null ? key : string.Format("{0}.{1}", module, key);
  40. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  41. {
  42. try
  43. {
  44. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  45. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  46. if (originValue != convertedValue)
  47. {
  48. pi.SetValue(target, convertedValue, null);
  49. }
  50. }
  51. catch (Exception ex)
  52. {
  53. LOG.Error("由RT返回的数据更新失败" + key, ex);
  54. }
  55. }
  56. });
  57. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  58. property =>
  59. {
  60. FieldInfo pi = (FieldInfo)property;
  61. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  62. string key = module == null ? $"{SystemName}.{subscription.ModuleKey}" : string.Format("{0}.{1}", module, subscription.ModuleKey);
  63. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  64. {
  65. try
  66. {
  67. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  68. pi.SetValue(target, convertedValue);
  69. }
  70. catch (Exception ex)
  71. {
  72. LOG.Error("由RT返回的数据更新失败" + key, ex);
  73. }
  74. }
  75. });
  76. }
  77. protected override void InvokePropertyChanged()
  78. {
  79. PropertyInfo[] ps = this.GetType().GetProperties();
  80. foreach (PropertyInfo p in ps)
  81. {
  82. if (!p.GetCustomAttributes(false).Any(attribute => attribute is IgnorePropertyChangeAttribute))
  83. InvokePropertyChanged(p.Name);
  84. if (p.PropertyType == typeof(ICommand))
  85. {
  86. if (p.GetValue(this, null) is IDelegateCommand cmd)
  87. cmd.RaiseCanExecuteChanged();
  88. }
  89. }
  90. FieldInfo[] fi = this.GetType().GetFields();
  91. foreach (FieldInfo p in fi)
  92. {
  93. InvokePropertyChanged(p.Name);
  94. if (p.FieldType == typeof(ICommand))
  95. {
  96. DelegateCommand<string> cmd = p.GetValue(this) as DelegateCommand<string>;
  97. if (cmd != null)
  98. cmd.RaiseCanExecuteChanged();
  99. }
  100. }
  101. //Parallel.ForEach(this.GetType().GetProperties(), property => InvokePropertyChanged(property.Name));
  102. }
  103. }
  104. public class UiViewModelBase : BaseModel
  105. {
  106. PeriodicJob _timer;
  107. protected ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
  108. protected Func<object, bool> _isSubscriptionAttribute;
  109. protected Func<MemberInfo, bool> _hasSubscriptionAttribute;
  110. public ICommand DeviceOperationCommand { get; private set; }
  111. public bool SetField<T>(ref T field, T value, string propertyName)
  112. {
  113. if (EqualityComparer<T>.Default.Equals(field, value)) return false;
  114. field = value;
  115. NotifyOfPropertyChange(propertyName);
  116. return true;
  117. }
  118. [Subscription("PM1.EnableMinics")]
  119. public bool EnableMinics { get; set; }
  120. public Dictionary<string, string> StockerToModuleDic
  121. {
  122. get
  123. {
  124. var moduleDic = new Dictionary<string, string>()
  125. {
  126. { "Stocker11", "Stocker1" },
  127. { "Stocker21", "Stocker2" },
  128. { "Stocker12", "Stocker3" },
  129. { "Stocker22", "Stocker4" },
  130. { "Stocker13", "Stocker5" },
  131. { "Stocker23", "Stocker6" },
  132. { "Stocker14", "Stocker7" },
  133. { "Stocker24", "Stocker8" },
  134. { "Stocker15", "Stocker9" },
  135. { "Stocker25", "Stocker10" },
  136. { "Stocker31", "Stocker11" },
  137. { "Stocker41", "Stocker12" },
  138. { "Stocker32", "Stocker13" },
  139. { "Stocker42", "Stocker14" },
  140. { "Stocker33", "Stocker15" },
  141. { "Stocker43", "Stocker16" },
  142. { "Stocker34", "Stocker17" },
  143. { "Stocker44", "Stocker18" },
  144. { "Stocker35", "Stocker19" },
  145. { "Stocker36", "Stocker20" },
  146. };
  147. return moduleDic;
  148. }
  149. }
  150. public Dictionary<string, string> ModuleToStockerDic
  151. {
  152. get
  153. {
  154. var moduleDic = new Dictionary<string, string>()
  155. {
  156. { "Stocker1", "Stocker11" },
  157. { "Stocker2", "Stocker21" },
  158. { "Stocker3", "Stocker12" },
  159. { "Stocker4", "Stocker22" },
  160. { "Stocker5", "Stocker13" },
  161. { "Stocker6", "Stocker23" },
  162. { "Stocker7", "Stocker14" },
  163. { "Stocker8", "Stocker24" },
  164. { "Stocker9", "Stocker15" },
  165. { "Stocker10", "Stocker25" },
  166. { "Stocker11", "Stocker31" },
  167. { "Stocker12", "Stocker41" },
  168. { "Stocker13", "Stocker32" },
  169. { "Stocker14", "Stocker42" },
  170. { "Stocker15", "Stocker33" },
  171. { "Stocker16", "Stocker43" },
  172. { "Stocker17", "Stocker34" },
  173. { "Stocker18", "Stocker44" },
  174. { "Stocker19", "Stocker35" },
  175. { "Stocker20", "Stocker36" },
  176. };
  177. return moduleDic;
  178. }
  179. }
  180. /// <summary>
  181. /// 是否在退出页面后,仍然在后台更新数据,默认不更新
  182. /// </summary>
  183. public bool ActiveUpdateData { get; set; }
  184. protected override void OnInitialize()
  185. {
  186. base.OnInitialize();
  187. DeviceOperationCommand = new DelegateCommand<object>(DeviceOperation);
  188. SubscribeKeys();
  189. }
  190. void DeviceOperation(object param)
  191. {
  192. //InvokeClient.Instance.Service.DoOperation(OperationName.DeviceOperation.ToString(), (object[])param);
  193. }
  194. public string GetUnitStatusBackground(string status)
  195. {
  196. return ModuleStatusBackground.GetStatusBackground(status);
  197. }
  198. public string GetUnitOnlineColor(bool isOnline)
  199. {
  200. return isOnline ? "LimeGreen" : "Black";
  201. }
  202. /// <summary>
  203. /// support wafer transfer for slot
  204. /// </summary>
  205. public virtual void OnWaferTransfer(DragDropEventArgs args)
  206. {
  207. try
  208. {
  209. WaferMoveManager.Instance.TransferWafer(args.TranferFrom, args.TranferTo);
  210. }
  211. catch (Exception ex)
  212. {
  213. LOG.Write(ex);
  214. }
  215. }
  216. /// <summary>
  217. /// support context menu
  218. /// </summary>
  219. public virtual void OnMouseUp(object sender, MouseButtonEventArgs e)
  220. {
  221. if (e.ChangedButton == MouseButton.Left)
  222. {
  223. //if (sender is Slot slot)
  224. //{
  225. // if (slot.WaferStatus == 0)
  226. // {
  227. // slot.WaferStatus = 1;
  228. // }
  229. // else if(slot.WaferStatus == 1)
  230. // {
  231. // slot.WaferStatus = 0;
  232. // }
  233. //}
  234. }
  235. else
  236. {
  237. if (e.ChangedButton != MouseButton.Right)
  238. return;
  239. if (sender is Slot slot)
  240. {
  241. ContextMenu cm = ContextMenuManager.Instance.GetSlotMenus(slot);
  242. if (cm != null)
  243. {
  244. ((FrameworkElement)e.Source).ContextMenu = cm;
  245. }
  246. return;
  247. }
  248. if (sender is CarrierContentControl carrier)
  249. {
  250. ContextMenu cm = ContextMenuManager.Instance.GetCarrierMenus(carrier);
  251. if (cm != null)
  252. {
  253. ((FrameworkElement)e.Source).ContextMenu = cm;
  254. }
  255. return;
  256. }
  257. }
  258. }
  259. public UiViewModelBase()
  260. {
  261. _timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
  262. _isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
  263. _hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
  264. }
  265. public Dictionary<string, Dictionary<string, string>> GetDevice(string deviceType, string deviceName, XDocument xmlDoc, string filterStr = "id")
  266. {
  267. if (string.IsNullOrEmpty(deviceType)) return default;
  268. Dictionary<string, Dictionary<string, string>> result = new Dictionary<string, Dictionary<string, string>>();
  269. var ioLpNodes = xmlDoc.Descendants(deviceType);
  270. foreach (var ioLpNode in ioLpNodes)
  271. {
  272. if (ioLpNode.Attribute(filterStr).Value != deviceName) continue;
  273. Dictionary<string, string> attributes = new Dictionary<string, string>();
  274. foreach (XAttribute attribute in ioLpNode.Attributes())
  275. {
  276. attributes[attribute.Name.LocalName] = attribute.Value;
  277. }
  278. result.Add(ioLpNode.Attribute(filterStr).Value, attributes);
  279. }
  280. return result;
  281. }
  282. //
  283. protected virtual bool OnTimer()
  284. {
  285. try
  286. {
  287. Poll();
  288. }
  289. catch (Exception ex)
  290. {
  291. LOG.Error(ex.Message);
  292. }
  293. return true;
  294. }
  295. public virtual void EnableTimer(bool enable)
  296. {
  297. if (enable) _timer.Start();
  298. else _timer.Pause();
  299. }
  300. protected virtual void Poll()
  301. {
  302. if (_subscribedKeys.Count > 0)
  303. {
  304. Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
  305. if (result == null)
  306. {
  307. LOG.Error("获取RT数据失败");
  308. return;
  309. }
  310. if (result.Count != _subscribedKeys.Count)
  311. {
  312. string unknowKeys = string.Empty;
  313. foreach (string key in _subscribedKeys)
  314. {
  315. if (!result.ContainsKey(key))
  316. {
  317. unknowKeys += key + "\r\n";
  318. }
  319. }
  320. //System.Diagnostics.Debug.Assert(false, unknowKeys);
  321. }
  322. InvokeBeforeUpdateProperty(result);
  323. UpdateValue(result);
  324. Application.Current?.Dispatcher.Invoke(new Action(() =>
  325. {
  326. InvokePropertyChanged();
  327. InvokeAfterUpdateProperty(result);
  328. }));
  329. }
  330. }
  331. public void InvokePropertyChanged(string propertyName)
  332. {
  333. NotifyOfPropertyChange(propertyName);
  334. }
  335. public void InvokeAllPropertyChanged()
  336. {
  337. PropertyInfo[] ps = this.GetType().GetProperties();
  338. foreach (PropertyInfo p in ps)
  339. {
  340. InvokePropertyChanged(p.Name);
  341. if (p.PropertyType == typeof(ICommand))
  342. {
  343. DelegateCommand<string> cmd = p.GetValue(this, null) as DelegateCommand<string>;
  344. if (cmd != null)
  345. cmd.RaiseCanExecuteChanged();
  346. }
  347. }
  348. }
  349. protected virtual void InvokePropertyChanged()
  350. {
  351. Refresh();
  352. }
  353. protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
  354. {
  355. }
  356. protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  357. {
  358. }
  359. protected void UpdateValue(Dictionary<string, object> data)
  360. {
  361. if (data == null)
  362. return;
  363. UpdateSubscribe(data, this);
  364. var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
  365. foreach (var property in properties)
  366. {
  367. var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
  368. UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
  369. }
  370. }
  371. public virtual void SubscribeKeys()
  372. {
  373. SubscribeKeys(this);
  374. }
  375. protected void Subscribe(string key)
  376. {
  377. if (!string.IsNullOrEmpty(key))
  378. {
  379. _subscribedKeys.Add(key);
  380. }
  381. }
  382. public void SubscribeKeys(UiViewModelBase target)
  383. {
  384. SubscribeKeys(target, "");
  385. }
  386. public void SubscribeKeys(UiViewModelBase target, string module)
  387. {
  388. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  389. property =>
  390. {
  391. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  392. string key = subscription.ModuleKey;
  393. if (!string.IsNullOrEmpty(module))
  394. {
  395. key = $"{module}.{key}";
  396. subscription.SetModule(module);
  397. }
  398. if (!_subscribedKeys.Contains(key))
  399. _subscribedKeys.Add(key);
  400. });
  401. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  402. method =>
  403. {
  404. SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  405. string key = subscription.ModuleKey;
  406. if (!string.IsNullOrEmpty(module))
  407. {
  408. key = $"{module}.{key}";
  409. subscription.SetModule(module);
  410. }
  411. if (!_subscribedKeys.Contains(key))
  412. _subscribedKeys.Add(key);
  413. });
  414. }
  415. public virtual void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  416. {
  417. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  418. property =>
  419. {
  420. PropertyInfo pi = (PropertyInfo)property;
  421. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  422. string key = subscription.ModuleKey;
  423. key = module == null ? key : string.Format("{0}.{1}", module, key);
  424. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  425. {
  426. try
  427. {
  428. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  429. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  430. if (originValue != convertedValue)
  431. {
  432. pi.SetValue(target, convertedValue, null);
  433. }
  434. }
  435. catch (Exception ex)
  436. {
  437. LOG.Error("由RT返回的数据更新失败" + key, ex);
  438. }
  439. }
  440. });
  441. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  442. property =>
  443. {
  444. FieldInfo pi = (FieldInfo)property;
  445. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  446. string key = subscription.ModuleKey;
  447. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  448. {
  449. try
  450. {
  451. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  452. pi.SetValue(target, convertedValue);
  453. }
  454. catch (Exception ex)
  455. {
  456. LOG.Error("由RT返回的数据更新失败" + key, ex);
  457. }
  458. }
  459. });
  460. }
  461. protected override void OnActivate()
  462. {
  463. base.OnActivate();
  464. EnableTimer(true);
  465. }
  466. protected override void OnDeactivate(bool close)
  467. {
  468. base.OnDeactivate(close);
  469. if (!ActiveUpdateData)
  470. {
  471. EnableTimer(false);
  472. }
  473. }
  474. }
  475. public class IODisplay : PropertyChangedBase
  476. {
  477. public string Key { get; set; }
  478. private object _value;
  479. public object Value
  480. {
  481. get { return _value; }
  482. set { _value = value; this.NotifyOfPropertyChange(nameof(Value)); }
  483. }
  484. private Visibility _Visiable=Visibility.Visible;
  485. public Visibility Visiable
  486. {
  487. get { return _Visiable; }
  488. set { _Visiable = value; this.NotifyOfPropertyChange(nameof(Visiable)); }
  489. }
  490. }
  491. public class UiWithIOViewModelBase : UiViewModelBase
  492. {
  493. private string _ModuleIndex;
  494. public string ModuleIndex
  495. {
  496. get { return _ModuleIndex; }
  497. set { _ModuleIndex = value; InitIO(); this.NotifyOfPropertyChange(nameof(ModuleIndex)); }
  498. }
  499. public string ModuleName { get; set; }
  500. public string PMModuleName
  501. {
  502. get {
  503. string targetModule = "";
  504. switch (ModuleName)
  505. {
  506. case "CRA":
  507. case "IRA":
  508. targetModule = ModuleName;
  509. break;
  510. case "PRA":
  511. targetModule = "PRA1";
  512. break;
  513. case "PRA1":
  514. case "PRA2":
  515. int index = int.Parse(ModuleIndex.Split('_')[1]) + 1;
  516. targetModule = $"PRA{index}";
  517. break;
  518. case "UNC":
  519. case "PUP":
  520. case "RCV":
  521. case "SND":
  522. case "RJC":
  523. targetModule = "Cassette" + ModuleIndex.Split('_')[1];
  524. break;
  525. default:
  526. targetModule = "PM" + ModuleIndex.Replace("-", "_");
  527. break;
  528. }
  529. return targetModule;
  530. }
  531. }
  532. public ObservableCollection<IODisplay> SignalsList { get; set; } = new ObservableCollection<IODisplay>();
  533. private string _strDI = "DIListString";
  534. public ObservableCollection<IODisplay> DIList { get; set; } = new ObservableCollection<IODisplay>();
  535. private string _strDO = "DOListString";
  536. public ObservableCollection<IODisplay> DOList { get; set; } = new ObservableCollection<IODisplay>();
  537. private string _strAI = "AIListString";
  538. public ObservableCollection<IODisplay> AIList { get; set; } = new ObservableCollection<IODisplay>();
  539. public override void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  540. {
  541. UpdateValue(SignalsList,data);
  542. UpdateValue(DIList, data);
  543. UpdateValue(DOList, data);
  544. UpdateValue(AIList, data);
  545. }
  546. private void UpdateValue(ObservableCollection<IODisplay> list, Dictionary<string, object> data)
  547. {
  548. foreach (var item in list)
  549. {
  550. if (data.ContainsKey($"{PMModuleName}.{item.Key}"))
  551. item.Value = data[$"{PMModuleName}.{item.Key}"];
  552. }
  553. }
  554. protected override void OnInitialize()
  555. {
  556. base.OnInitialize();
  557. InitIO();
  558. }
  559. public void InitIO()
  560. {
  561. InitSignals();
  562. InitDI();
  563. InitDO();
  564. InitAI();
  565. }
  566. protected virtual void InitSignals()
  567. {
  568. }
  569. private void InitDI()
  570. {
  571. DIList.Clear();
  572. string strKey = $"{PMModuleName}.{_strDI}";
  573. var strDIValue = QueryDataClient.Instance.Service.PollData(new string[] { strKey });
  574. if (strDIValue == null || strDIValue.Count <= 0) return;
  575. var strDIValues = strDIValue[strKey].ToString().Split(',');
  576. foreach (var item in strDIValues)
  577. {
  578. base.Subscribe($"{PMModuleName}.{item}");
  579. DIList.Add(new IODisplay() { Key = item });
  580. }
  581. }
  582. private void InitDO()
  583. {
  584. DOList.Clear();
  585. string strKey = $"{PMModuleName}.{_strDO}";
  586. var strDOValue = QueryDataClient.Instance.Service.PollData(new string[] { strKey });
  587. if (strDOValue == null || strDOValue.Count <= 0) return;
  588. var strDOValues = strDOValue[strKey].ToString().Split(',');
  589. foreach (var item in strDOValues)
  590. {
  591. base.Subscribe($"{PMModuleName}.{item}");
  592. DOList.Add(new IODisplay() { Key = item });
  593. }
  594. }
  595. private void InitAI()
  596. {
  597. AIList.Clear();
  598. string strKey = $"{PMModuleName}.{_strAI}";
  599. var strAIValue = QueryDataClient.Instance.Service.PollData(new string[] { strKey });
  600. if (strAIValue == null || strAIValue.Count <= 0) return;
  601. var strAIValues = strAIValue[strKey].ToString().Split(',');
  602. foreach (var item in strAIValues)
  603. {
  604. base.Subscribe($"{PMModuleName}.{item}");
  605. AIList.Add(new IODisplay() { Key = item });
  606. }
  607. }
  608. protected bool GetDIValue(string key)
  609. {
  610. bool bRet=false;
  611. Parallel.ForEach(DIList.Where(x => x.Key == key),
  612. property =>
  613. {
  614. bool.TryParse(property.Value?.ToString(), out bRet);
  615. });
  616. return bRet;
  617. }
  618. protected T GetSignalValue<T>(string key)
  619. {
  620. T ret = default(T);
  621. Parallel.ForEach(SignalsList.Where(x => x.Key == key),
  622. property=>
  623. {
  624. if (property.Value != null)
  625. ret = (T)(object)property.Value;
  626. });
  627. return ret;
  628. }
  629. }
  630. }