StandardHotMetalDevice.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.OperationCenter;
  5. using Aitex.Core.RT.Routine;
  6. using Aitex.Core.UI.Control;
  7. using Aitex.Core.Util;
  8. using MECF.Framework.Common.Beckhoff.ModuleIO;
  9. using MECF.Framework.Common.CommonData.Metal;
  10. using MECF.Framework.Common.Persistent.Reservoirs;
  11. using MECF.Framework.Common.TwinCat;
  12. using CyberX8_Core;
  13. using CyberX8_RT.Devices.LinMot;
  14. using CyberX8_RT.Devices.Prewet;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Reflection;
  19. using System.Diagnostics;
  20. using MECF.Framework.Common.IOCore;
  21. namespace CyberX8_RT.Devices.Metal
  22. {
  23. public class StandardHotMetalDevice : MetalCellDevice
  24. {
  25. private enum MetalOperation
  26. {
  27. None,
  28. CellPumpOn
  29. }
  30. #region 常量
  31. private const string PERSISTENT_VALUE = "PersistentValue";
  32. private const string CELL_PUMP = "CellPump";
  33. private const string CELL_FLOW = "CellFlow";
  34. private const string WH_CLAMP = "WaferHolderClamp";
  35. private const string CIRCULATION = "Circulation";
  36. #endregion
  37. #region 内部变量
  38. /// <summary>
  39. /// 设备数据
  40. /// </summary>
  41. private StandardHotMetalDeviceData _metalDeviceData = new StandardHotMetalDeviceData();
  42. /// <summary>
  43. /// 变量是否初始化字典
  44. /// </summary>
  45. private Dictionary<string, bool> _variableInitializeDic = new Dictionary<string, bool>();
  46. /// <summary>
  47. /// Pump Routine
  48. /// </summary>
  49. private StandardHotMetalCellPumpRoutine _cellPumpRoutine;
  50. /// <summary>
  51. /// 当前操作
  52. /// </summary>
  53. private MetalOperation _currentOperation;
  54. /// <summary>
  55. /// Flow Valve计时
  56. /// </summary>
  57. private Stopwatch _flowValveStopWatch = new Stopwatch();
  58. #endregion
  59. #region 属性
  60. /// <summary>
  61. /// 设备数据
  62. /// </summary>
  63. public StandardHotMetalDeviceData MetalDeviceData { get { return _metalDeviceData; } }
  64. /// <summary>
  65. /// Flow Valve稳定状态
  66. /// </summary>
  67. public bool FlowValveStable { get { return _metalDeviceData.Circulation && _flowValveStopWatch.ElapsedMilliseconds >= 3000; } }
  68. #endregion
  69. /// <summary>
  70. /// 构造函数
  71. /// </summary>
  72. /// <param name="moduleName"></param>
  73. public StandardHotMetalDevice(string moduleName) : base(moduleName)
  74. {
  75. }
  76. /// <summary>
  77. /// 初始化
  78. /// </summary>
  79. /// <returns></returns>
  80. public override bool Initialize()
  81. {
  82. base.Initialize();
  83. InitializeParameter();
  84. InitializeRoutine();
  85. SubscribeValueAction();
  86. SubscribeData();
  87. return true;
  88. }
  89. /// <summary>
  90. /// 初始化参数
  91. /// </summary>
  92. private void InitializeParameter()
  93. {
  94. _persistentValue = MetalPersistentManager.Instance.GetMetalPersistentValue(Module);
  95. if (_persistentValue == null)
  96. {
  97. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Persistent Value Object is not exist");
  98. }
  99. }
  100. /// <summary>
  101. /// 初始化Routine
  102. /// </summary>
  103. private void InitializeRoutine()
  104. {
  105. _cellPumpRoutine = new StandardHotMetalCellPumpRoutine(Module.ToString());
  106. }
  107. /// <summary>
  108. /// 订阅数据
  109. /// </summary>
  110. private void SubscribeData()
  111. {
  112. DATA.Subscribe($"{Module}.MetalData", () => _metalDeviceData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  113. DATA.Subscribe($"{Module}.CellPumpEnable", () => _metalDeviceData.CellPump, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  114. DATA.Subscribe($"{Module}.WaferShuttleClamped", () => _metalDeviceData.WaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  115. DATA.Subscribe($"{Module}.CellFlow", () => _metalDeviceData.CellFlow, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  116. DATA.Subscribe($"{Module}.Circulation", () => _metalDeviceData.Circulation, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  117. }
  118. /// <summary>
  119. /// 订阅变量数值发生变化
  120. /// </summary>
  121. private void SubscribeValueAction()
  122. {
  123. BeckhoffIoSubscribeUpdateVariable(CELL_PUMP);
  124. BeckhoffIoSubscribeUpdateVariable(CELL_FLOW);
  125. BeckhoffIoSubscribeUpdateVariable(WH_CLAMP);
  126. BeckhoffIoSubscribeUpdateVariable(CIRCULATION);
  127. }
  128. /// <summary>
  129. /// 订阅Operation
  130. /// </summary>
  131. protected override void InitializeOperation()
  132. {
  133. base.InitializeOperation();
  134. OP.Subscribe($"{Module}.PumpEnable", (cmd, args) => { return PumpOnOperation(cmd, args); });
  135. OP.Subscribe($"{Module}.PumpDisable", (cmd, args) => { return PumpOffOperation(cmd, args); });
  136. OP.Subscribe($"{Module}.CellSwitchToBypass", (cmd, args) => { return SwitchToBypass(cmd, args); });
  137. OP.Subscribe($"{Module}.CellSwitchToFlow", (cmd, args) => { return SwitchToFlow(cmd, args); });
  138. OP.Subscribe($"{Module}.ClampOn", (cmd, args) => { return WaferHolderClampOn(cmd, args); });
  139. OP.Subscribe($"{Module}.ClampOff", (cmd, args) => { return WaferHolderClampOff(cmd, args); });
  140. OP.Subscribe($"{Module}.WaferHolderClampOn", (cmd, args) => { return WaferHolderClampOn(cmd, args); });
  141. OP.Subscribe($"{Module}.WaferHolderUnclampOn", (cmd, args) => { return WaferHolderClampOff(cmd, args); });
  142. }
  143. /// <summary>
  144. /// 订阅IO变量
  145. /// </summary>
  146. /// <param name="variable"></param>
  147. private void BeckhoffIoSubscribeUpdateVariable(string variable)
  148. {
  149. _variableInitializeDic[variable] = false;
  150. IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
  151. }
  152. /// <summary>
  153. /// 更新变量数值
  154. /// </summary>
  155. /// <param name="variable"></param>
  156. /// <param name="value"></param>
  157. private void UpdateVariableValue(string variable, object value)
  158. {
  159. if (!_metalDeviceData.IsDataInitialized)
  160. {
  161. _metalDeviceData.IsDataInitialized = true;
  162. }
  163. PropertyInfo property = _metalDeviceData.GetType().GetProperty(variable);
  164. if (property != null)
  165. {
  166. property.SetValue(_metalDeviceData, value);
  167. }
  168. if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
  169. {
  170. _variableInitializeDic[variable] = true;
  171. }
  172. if (variable == CIRCULATION)
  173. {
  174. bool bValue = (bool)value;
  175. if (bValue)
  176. {
  177. _flowValveStopWatch.Restart();
  178. }
  179. }
  180. }
  181. #region CellPump
  182. /// <summary>
  183. /// Cell Pump On操作
  184. /// </summary>
  185. /// <param name="cmd"></param>
  186. /// <param name="param"></param>
  187. /// <returns></returns>
  188. public bool PumpOnOperation(string cmd, object[] param)
  189. {
  190. if (_status == RState.Running)
  191. {
  192. LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump On");
  193. return false;
  194. }
  195. _status = _cellPumpRoutine.Start(true);
  196. _currentOperation = MetalOperation.CellPumpOn;
  197. return _status == RState.Running;
  198. }
  199. /// <summary>
  200. /// Cell Pump Off操作
  201. /// </summary>
  202. /// <param name="cmd"></param>
  203. /// <param name="param"></param>
  204. /// <returns></returns>
  205. public bool PumpOffOperation(string cmd, object[] param)
  206. {
  207. return PumpOff();
  208. }
  209. /// <summary>
  210. /// Pump Off
  211. /// </summary>
  212. /// <returns></returns>
  213. public bool PumpOff()
  214. {
  215. if (_status == RState.Running && _currentOperation == MetalOperation.CellPumpOn)
  216. {
  217. IRoutine routine = GetCurrentRoutine();
  218. if (routine != null)
  219. {
  220. routine.Abort();
  221. }
  222. }
  223. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CELL_PUMP}");
  224. return IOModuleManager.Instance.WriteIoValue(ioName, false);
  225. }
  226. #endregion
  227. #region WaferHolderClampOn
  228. /// <summary>
  229. /// Wafer Holder Clamp On
  230. /// </summary>
  231. /// <param name="cmd"></param>
  232. /// <param name="param"></param>
  233. /// <returns></returns>
  234. public bool WaferHolderClampOn(string cmd, object[] param)
  235. {
  236. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WH_CLAMP}");
  237. return IOModuleManager.Instance.WriteIoValue(ioName, true);
  238. }
  239. #endregion
  240. #region WaferHolderClampOff
  241. /// <summary>
  242. /// Wafer Holder Clamp On
  243. /// </summary>
  244. /// <param name="cmd"></param>
  245. /// <param name="param"></param>
  246. /// <returns></returns>
  247. public bool WaferHolderClampOff(string cmd, object[] param)
  248. {
  249. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WH_CLAMP}");
  250. return IOModuleManager.Instance.WriteIoValue(ioName, false);
  251. }
  252. #endregion
  253. #region circulation
  254. /// <summary>
  255. /// 切换至Bypass
  256. /// </summary>
  257. /// <returns></returns>
  258. public bool SwitchToBypass(string cmd, object[] param)
  259. {
  260. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CIRCULATION}");
  261. return IOModuleManager.Instance.WriteIoValue(ioName, false);
  262. }
  263. /// <summary>
  264. /// 切换至Flow
  265. /// </summary>
  266. /// <returns></returns>
  267. public bool SwitchToFlow(string cmd, object[] param)
  268. {
  269. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CIRCULATION}");
  270. return IOModuleManager.Instance.WriteIoValue(ioName, true);
  271. }
  272. #endregion
  273. /// <summary>
  274. /// Enter Disabled Operation
  275. /// </summary>
  276. /// <returns></returns>
  277. public void EnterDisabledOperation()
  278. {
  279. if (_metalDeviceData.CellPump)
  280. {
  281. PumpOffOperation("", null);
  282. }
  283. }
  284. /// <summary>
  285. /// 定时器
  286. /// </summary>
  287. /// <returns></returns>
  288. public override bool OnTimer(int interval)
  289. {
  290. if (_status == RState.Running)
  291. {
  292. IRoutine routine = GetCurrentRoutine();
  293. if (routine != null)
  294. {
  295. RState rsState = routine.Monitor();
  296. if (rsState == RState.Failed || rsState == RState.Timeout)
  297. {
  298. _status = RState.Failed;
  299. PumpOff();
  300. _currentOperation = MetalOperation.None;
  301. }
  302. else if (rsState == RState.End)
  303. {
  304. _status = RState.End;
  305. _currentOperation = MetalOperation.None;
  306. }
  307. }
  308. }
  309. return true;
  310. }
  311. /// <summary>
  312. /// 当前Routine;
  313. /// </summary>
  314. /// <returns></returns>
  315. private IRoutine GetCurrentRoutine()
  316. {
  317. switch (_currentOperation)
  318. {
  319. case MetalOperation.CellPumpOn:
  320. return _cellPumpRoutine;
  321. default:
  322. return null;
  323. }
  324. }
  325. #region 设备接口
  326. public override void Monitor()
  327. {
  328. }
  329. public override void Reset()
  330. {
  331. }
  332. public override void Terminate()
  333. {
  334. }
  335. #endregion
  336. }
  337. }