UIViewModelBase.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Input;
  10. using Aitex.Core.RT.Log;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.UI.MVVM;
  13. using Aitex.Core.Util;
  14. using Aitex.Core.Utilities;
  15. using MECF.Framework.Common.DataCenter;
  16. using MECF.Framework.Common.OperationCenter;
  17. using OpenSEMI.ClientBase;
  18. using OpenSEMI.Ctrlib.Controls;
  19. using Virgo_D.UI.Config;
  20. using Virgo_DCommon;
  21. namespace Virgo_DUI.Client.Models.Sys
  22. {
  23. public class ModuleUiViewModelBase : UiViewModelBase
  24. {
  25. public string SystemName { get; set; }
  26. public override void SubscribeKeys()
  27. {
  28. SubscribeKeys(this, SystemName);
  29. }
  30. public override void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  31. {
  32. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  33. property =>
  34. {
  35. PropertyInfo pi = (PropertyInfo)property;
  36. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  37. string key = module == null ? $"{SystemName}.{subscription.ModuleKey}" : string.Format("{0}.{1}", module, subscription.ModuleKey);
  38. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  39. {
  40. try
  41. {
  42. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  43. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  44. if (originValue != convertedValue)
  45. {
  46. pi.SetValue(target, convertedValue, null);
  47. }
  48. }
  49. catch (Exception ex)
  50. {
  51. LOG.Error("由RT返回的数据更新失败" + key, ex);
  52. }
  53. }
  54. });
  55. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  56. property =>
  57. {
  58. FieldInfo pi = (FieldInfo)property;
  59. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  60. string key = module == null ? $"{SystemName}.{subscription.ModuleKey}" : string.Format("{0}.{1}", module, subscription.ModuleKey);
  61. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  62. {
  63. try
  64. {
  65. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  66. pi.SetValue(target, convertedValue);
  67. }
  68. catch (Exception ex)
  69. {
  70. LOG.Error("由RT返回的数据更新失败" + key, ex);
  71. }
  72. }
  73. });
  74. }
  75. public void InvokePropertyChanged(string propertyName)
  76. {
  77. NotifyOfPropertyChange(propertyName);
  78. }
  79. public void InvokeAllPropertyChanged()
  80. {
  81. PropertyInfo[] ps = this.GetType().GetProperties();
  82. foreach (PropertyInfo p in ps)
  83. {
  84. InvokePropertyChanged(p.Name);
  85. if (p.PropertyType == typeof(ICommand))
  86. {
  87. DelegateCommand<string> cmd = p.GetValue(this, null) as DelegateCommand<string>;
  88. if (cmd != null)
  89. cmd.RaiseCanExecuteChanged();
  90. }
  91. }
  92. FieldInfo[] fi = this.GetType().GetFields();
  93. foreach (FieldInfo p in fi)
  94. {
  95. InvokePropertyChanged(p.Name);
  96. if (p.FieldType == typeof(ICommand))
  97. {
  98. DelegateCommand<string> cmd = p.GetValue(this) as DelegateCommand<string>;
  99. if (cmd != null)
  100. cmd.RaiseCanExecuteChanged();
  101. }
  102. }
  103. //Parallel.ForEach(this.GetType().GetProperties(), property => InvokePropertyChanged(property.Name));
  104. }
  105. protected override void InvokePropertyChanged()
  106. {
  107. PropertyInfo[] ps = this.GetType().GetProperties();
  108. foreach (PropertyInfo p in ps)
  109. {
  110. if (!p.GetCustomAttributes(false).Any(attribute => attribute is IgnorePropertyChangeAttribute))
  111. InvokePropertyChanged(p.Name);
  112. if (p.PropertyType == typeof(ICommand))
  113. {
  114. if (p.GetValue(this, null) is IDelegateCommand cmd)
  115. cmd.RaiseCanExecuteChanged();
  116. }
  117. }
  118. FieldInfo[] fi = this.GetType().GetFields();
  119. foreach (FieldInfo p in fi)
  120. {
  121. InvokePropertyChanged(p.Name);
  122. if (p.FieldType == typeof(ICommand))
  123. {
  124. DelegateCommand<string> cmd = p.GetValue(this) as DelegateCommand<string>;
  125. if (cmd != null)
  126. cmd.RaiseCanExecuteChanged();
  127. }
  128. }
  129. //Parallel.ForEach(this.GetType().GetProperties(), property => InvokePropertyChanged(property.Name));
  130. }
  131. }
  132. public class UiViewModelBase : BaseModel
  133. {
  134. private PeriodicJob _timer;
  135. protected ConcurrentBag<string> _subscribedKeys = new ConcurrentBag<string>();
  136. protected Func<object, bool> _isSubscriptionAttribute;
  137. protected Func<MemberInfo, bool> _hasSubscriptionAttribute;
  138. [IgnorePropertyChange]
  139. public List<Tuple<string, string, string, bool>> _allDataItems = new List<Tuple<string, string, string, bool>>();
  140. #region Property
  141. public ModuleInfo FOUPA { get; set; }
  142. public ModuleInfo FOUPB { get; set; }
  143. public ModuleInfo EFEM { get; set; }
  144. public ModuleInfo Aligner1 { get; set; }
  145. public ModuleInfo Aligner2 { get; set; }
  146. public ModuleInfo PMA { get; set; }
  147. public ModuleInfo PMB { get; set; }
  148. #region Wafer info for machine
  149. public WaferInfo PMAWafer { get; set; }
  150. public WaferInfo PMBWafer { get; set; }
  151. public WaferInfo Aligner1Wafer { get; set; }
  152. public WaferInfo Aligner2Wafer { get; set; }
  153. public WaferInfo EfemRobotWafer1 { get; set; }
  154. public Dictionary<string, float> ModuleTemperature { get; set; }
  155. #endregion Wafer info for machine
  156. public ICommand DeviceOperationCommand { get; protected set; }
  157. #endregion Property
  158. protected override void OnInitialize()
  159. {
  160. base.OnInitialize();
  161. DeviceOperationCommand = new DelegateCommand<object>(DeviceOperation);
  162. ModuleTemperature = new Dictionary<string, float>();
  163. SubscribeKeys();
  164. }
  165. void DeviceOperation(object param)
  166. {
  167. InvokeClient.Instance.Service.DoOperation(RtOperation.DeviceOperation.ToString(), (object[])param);
  168. }
  169. protected void InitModules()
  170. {
  171. EFEM = ModuleManager.ModuleInfos["EfemRobot"];
  172. if (ModuleManager.ModuleInfos.ContainsKey("EfemRobot"))
  173. EfemRobotWafer1 = ModuleManager.ModuleInfos["EfemRobot"].WaferManager.Wafers[0];
  174. Aligner1 = ModuleManager.ModuleInfos["Aligner1"];
  175. if (ModuleManager.ModuleInfos.ContainsKey("Aligner1"))
  176. Aligner1Wafer = ModuleManager.ModuleInfos["Aligner1"].WaferManager.Wafers[0];
  177. Aligner2 = ModuleManager.ModuleInfos["Aligner2"];
  178. if (ModuleManager.ModuleInfos.ContainsKey("Aligner2"))
  179. Aligner2Wafer = ModuleManager.ModuleInfos["Aligner2"].WaferManager.Wafers[0];
  180. FOUPA = ModuleManager.ModuleInfos["LP1"];
  181. FOUPB = ModuleManager.ModuleInfos["LP2"];
  182. if (ModuleManager.ModuleInfos.ContainsKey("PMA"))
  183. {
  184. PMA = ModuleManager.ModuleInfos["PMA"];
  185. PMAWafer = ModuleManager.ModuleInfos["PMA"].WaferManager.Wafers[0];
  186. }
  187. if (ModuleManager.ModuleInfos.ContainsKey("PMB"))
  188. {
  189. PMB = ModuleManager.ModuleInfos["PMB"];
  190. PMBWafer = ModuleManager.ModuleInfos["PMB"].WaferManager.Wafers[0];
  191. }
  192. }
  193. public string GetUnitStatusBackground(string status)
  194. {
  195. if (status != null)
  196. status = status.Trim().ToLower();
  197. switch (status)
  198. {
  199. case "error":
  200. return "red";
  201. case "idle":
  202. return "Transparent";
  203. case "init":
  204. return "Yellow";
  205. default:
  206. return "LawnGreen";
  207. }
  208. }
  209. /// <summary>
  210. /// support wafer transfer for slot
  211. /// </summary>
  212. public void OnWaferTransfer(DragDropEventArgs args)
  213. {
  214. try
  215. {
  216. float temp = 0.0f;
  217. if (ModuleTemperature.ContainsKey(args.TranferTo.ModuleID))
  218. {
  219. temp = ModuleTemperature[args.TranferTo.ModuleID];
  220. }
  221. WaferMoveManager.Instance.TransferWafer(args.TranferFrom, args.TranferTo, temp);
  222. }
  223. catch (Exception ex)
  224. {
  225. LOG.Write(ex);
  226. }
  227. }
  228. /// <summary>
  229. /// support context menu
  230. /// </summary>
  231. public void OnMouseUp(object sender, MouseButtonEventArgs e)
  232. {
  233. if (e.ChangedButton == MouseButton.Right)
  234. {
  235. Slot slot = sender as Slot;
  236. ContextMenu cm = ContextMenuManager.Instance.GetSlotMenus(slot);
  237. if (cm != null)
  238. {
  239. ((FrameworkElement)e.Source).ContextMenu = cm;
  240. }
  241. }
  242. }
  243. public UiViewModelBase()
  244. {
  245. _timer = new PeriodicJob(1000, this.OnTimer, "UIUpdaterThread - " + GetType().Name);
  246. _isSubscriptionAttribute = attribute => attribute is SubscriptionAttribute;
  247. _hasSubscriptionAttribute = mi => mi.GetCustomAttributes(false).Any(_isSubscriptionAttribute);
  248. _allDataItems = SystemConfigManager.Instance.GetMonitorDataList();
  249. }
  250. public virtual void SubscribeKeys()
  251. {
  252. SubscribeKeys(this);
  253. }
  254. //
  255. protected virtual bool OnTimer()
  256. {
  257. try
  258. {
  259. Poll();
  260. }
  261. catch (Exception ex)
  262. {
  263. LOG.Error(ex.Message);
  264. }
  265. return true;
  266. }
  267. public virtual void EnableTimer(bool enable)
  268. {
  269. if (enable) _timer.Start();
  270. else _timer.Pause();
  271. }
  272. protected virtual void Poll()
  273. {
  274. if (_subscribedKeys.Count > 0)
  275. {
  276. Dictionary<string, object> result = QueryDataClient.Instance.Service.PollData(_subscribedKeys);
  277. if (result == null)
  278. {
  279. LOG.Error("获取RT数据失败");
  280. return;
  281. }
  282. if (result.Count != _subscribedKeys.Count)
  283. {
  284. string unknowKeys = string.Empty;
  285. foreach (string key in _subscribedKeys)
  286. {
  287. if (!result.ContainsKey(key))
  288. {
  289. unknowKeys += key + "\r\n";
  290. }
  291. }
  292. //System.Diagnostics.Debug.Assert(false, unknowKeys);
  293. }
  294. InvokeBeforeUpdateProperty(result);
  295. UpdateValue(result);
  296. Application.Current.Dispatcher.Invoke(new Action(() =>
  297. {
  298. InvokePropertyChanged();
  299. InvokeAfterUpdateProperty(result);
  300. }));
  301. }
  302. }
  303. protected virtual void InvokePropertyChanged()
  304. {
  305. Refresh();
  306. }
  307. protected virtual void InvokeBeforeUpdateProperty(Dictionary<string, object> data)
  308. {
  309. }
  310. protected virtual void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  311. {
  312. }
  313. public Dictionary<string, Tuple<string, string, bool>> GetDataElements(string culture)
  314. {
  315. Dictionary<string, Tuple<string, string, bool>> result = new Dictionary<string, Tuple<string, string, bool>>();
  316. Dictionary<string, Tuple<string, string, string, bool>> all = GetDataElements();
  317. foreach (var tuple in all)
  318. {
  319. result.Add(tuple.Key, Tuple.Create(tuple.Value.Item1, culture == CultureSupported.Chinese ? tuple.Value.Item3 : tuple.Value.Item2, tuple.Value.Item4));
  320. }
  321. return result;
  322. }
  323. public Dictionary<string, Tuple<string, string, string, bool>> GetDataElements()
  324. {
  325. Dictionary<string, Tuple<string, string, string, bool>> dicItems = new Dictionary<string, Tuple<string, string, string, bool>>();
  326. foreach (var dataItem in _allDataItems)
  327. {
  328. dicItems[dataItem.Item1] = dataItem;
  329. }
  330. return dicItems;
  331. }
  332. void UpdateGasItem(bool enable, string display, string id, string key, Dictionary<string, Tuple<string, string, string, bool>> dicItems)
  333. {
  334. if (enable && dicItems.ContainsKey(key))
  335. {
  336. dicItems[key] = Tuple.Create(key,
  337. dicItems[key].Item2.Replace(id, display),
  338. dicItems[key].Item3.Replace(id, display),
  339. dicItems[key].Item4);
  340. }
  341. else
  342. {
  343. dicItems.Remove(key);
  344. }
  345. }
  346. void UpdateValue(Dictionary<string, object> data)
  347. {
  348. if (data == null)
  349. return;
  350. UpdateSubscribe(data, this);
  351. var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<SubscriptionModuleAttribute>() != null);
  352. foreach (var property in properties)
  353. {
  354. var moduleAttr = property.GetCustomAttribute<SubscriptionModuleAttribute>();
  355. UpdateSubscribe(data, property.GetValue(this), moduleAttr.Module);
  356. }
  357. }
  358. protected void Subscribe(string key)
  359. {
  360. if (!string.IsNullOrEmpty(key))
  361. {
  362. _subscribedKeys.Add(key);
  363. }
  364. }
  365. public void SubscribeKeys(UiViewModelBase target)
  366. {
  367. SubscribeKeys(target, "");
  368. }
  369. public void SubscribeKeys(UiViewModelBase target, string module)
  370. {
  371. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  372. property =>
  373. {
  374. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  375. string key = subscription.ModuleKey;
  376. if (!string.IsNullOrEmpty(module))
  377. {
  378. key = $"{module}.{key}";
  379. subscription.SetModule(module);
  380. }
  381. if (!_subscribedKeys.Contains(key))
  382. _subscribedKeys.Add(key);
  383. });
  384. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  385. method =>
  386. {
  387. SubscriptionAttribute subscription = method.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  388. string key = subscription.ModuleKey;
  389. if (!string.IsNullOrEmpty(module))
  390. {
  391. key = $"{module}.{key}";
  392. subscription.SetModule(module);
  393. }
  394. if (!_subscribedKeys.Contains(key))
  395. _subscribedKeys.Add(key);
  396. });
  397. }
  398. public virtual void UpdateSubscribe(Dictionary<string, object> data, object target, string module = null)
  399. {
  400. Parallel.ForEach(target.GetType().GetProperties().Where(_hasSubscriptionAttribute),
  401. property =>
  402. {
  403. PropertyInfo pi = (PropertyInfo)property;
  404. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  405. string key = subscription.ModuleKey;
  406. key = module == null ? key : string.Format("{0}.{1}", module, key);
  407. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  408. {
  409. try
  410. {
  411. var convertedValue = Convert.ChangeType(data[key], pi.PropertyType);
  412. var originValue = Convert.ChangeType(pi.GetValue(target, null), pi.PropertyType);
  413. if (originValue != convertedValue)
  414. {
  415. pi.SetValue(target, convertedValue, null);
  416. }
  417. }
  418. catch (Exception ex)
  419. {
  420. LOG.Error("由RT返回的数据更新失败" + key, ex);
  421. }
  422. }
  423. });
  424. Parallel.ForEach(target.GetType().GetFields().Where(_hasSubscriptionAttribute),
  425. property =>
  426. {
  427. FieldInfo pi = (FieldInfo)property;
  428. SubscriptionAttribute subscription = property.GetCustomAttributes(false).First(_isSubscriptionAttribute) as SubscriptionAttribute;
  429. string key = subscription.ModuleKey;
  430. if (_subscribedKeys.Contains(key) && data.ContainsKey(key))
  431. {
  432. try
  433. {
  434. var convertedValue = Convert.ChangeType(data[key], pi.FieldType);
  435. pi.SetValue(target, convertedValue);
  436. }
  437. catch (Exception ex)
  438. {
  439. LOG.Error("由RT返回的数据更新失败" + key, ex);
  440. }
  441. }
  442. });
  443. }
  444. protected override void OnActivate()
  445. {
  446. base.OnActivate();
  447. EnableTimer(true);
  448. }
  449. protected override void OnDeactivate(bool close)
  450. {
  451. base.OnDeactivate(close);
  452. EnableTimer(false);
  453. }
  454. }
  455. }