StandardHotMetalDevice.cs 13 KB

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