PlatingCellDevice.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.RT.Routine;
  7. using Aitex.Core.RT.SCCore;
  8. using Aitex.Core.Util;
  9. using MECF.Framework.Common.Beckhoff.ModuleIO;
  10. using MECF.Framework.Common.CommonData.PlatingCell;
  11. using MECF.Framework.Common.CommonData.Reservoir;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.IOCore;
  14. using MECF.Framework.Common.Persistent.Reservoirs;
  15. using MECF.Framework.Common.ToolLayout;
  16. using MECF.Framework.RT.Core.Equipments;
  17. using PunkHPX8_Core;
  18. using PunkHPX8_RT.Devices.AXIS;
  19. using PunkHPX8_RT.Devices.LinMot;
  20. using PunkHPX8_RT.Devices.PowerSupplier;
  21. using PunkHPX8_RT.Devices.Reservoir;
  22. using PunkHPX8_RT.Devices.SRD;
  23. using PunkHPX8_RT.Devices.VpwMain;
  24. using PunkHPX8_RT.Modules;
  25. using PunkHPX8_RT.Modules.PlatingCell;
  26. using PunkHPX8_RT.Modules.Reservoir;
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Linq;
  30. using System.Reflection;
  31. using System.Text;
  32. using System.Threading.Tasks;
  33. using System.Windows.Media.Animation;
  34. namespace PunkHPX8_RT.Devices.PlatingCell
  35. {
  36. public class PlatingCellDevice : BaseDevice, IDevice
  37. {
  38. /// <summary>
  39. /// Srd操作枚举
  40. /// </summary>
  41. private enum PlatingCellCommonOperation
  42. {
  43. None,
  44. ClamShellClose,
  45. ClamShellOpen,
  46. BiRotation,
  47. }
  48. #region 常量
  49. private const string PERSISTENT_VALUE = "PersistentValue";
  50. private const string PLATINGCELLDATA = "PlatingCellData";
  51. private const string AUTO = "Auto";
  52. private const string MANUAL = "Manual";
  53. private const string STRATUS = "Stratus";
  54. private const string DISABLED = "Disabled";
  55. private const string IS_HEAD_TILT = "IsHeadTilt";
  56. private const string IS_HEAD_VERTICAL = "IsHeadVertical";
  57. private const string CLAMSHELL_DISTANCE = "ClamShellDistance";
  58. private const string CLAMSHELL_CYLINDER_PRESSURE = "ClamShellCylinderPressure";
  59. private const string OVERFLOW_LEVEL = "OverFlowLevel";
  60. private const string CLAMSHELL_CLOSE = "ClamShellClose";
  61. private const string HEAD_TILT = "HeadTilt";
  62. private const string CCR_ENABLE = "CCREnable";
  63. private const string RINSE_ENABLE = "RinseEnable";
  64. #endregion
  65. #region 内部变量
  66. /// <summary>
  67. /// 当前操作
  68. /// </summary>
  69. private PlatingCellCommonOperation _currentOperation;
  70. /// <summary>
  71. /// clamshell routine操作
  72. /// </summary>
  73. private ClamShellCloseRoutine _closeRoutine;
  74. /// <summary>
  75. /// 电机双向旋转操作
  76. /// </summary>
  77. private RotationBiDirectionRoutine _biDirectionRoutine;
  78. /// 变量是否初始化字典
  79. /// </summary>
  80. private Dictionary<string, bool> _variableInitializeDic = new Dictionary<string, bool>();
  81. /// <summary>
  82. /// 操作当前状态
  83. /// </summary>
  84. protected RState _status;
  85. /// <summary>
  86. /// 持久化数据
  87. /// </summary>
  88. protected PlatingCellPersistentValue _persistentValue;
  89. /// <summary>
  90. /// PlatingCell项
  91. /// </summary>
  92. private PlatingCellItem _platingCellItem;
  93. /// <summary>
  94. /// overflow
  95. /// </summary>
  96. private int _overflowLevelHigh = 85;
  97. private int _overflowLevelLow = 25;
  98. /// <summary>
  99. /// 对应reservoir的名字
  100. /// </summary>
  101. private string _reservoirName;
  102. /// <summary>
  103. /// PowerSupplier
  104. /// </summary>
  105. protected CellPowerSupplier _powerSupplier;
  106. /// <summary>
  107. /// vertical电机
  108. /// </summary>
  109. private JetAxisBase _verticalAxis;
  110. /// <summary>
  111. /// vertical电机
  112. /// </summary>
  113. private JetAxisBase _rotationAxis;
  114. /// <summary>
  115. /// CCR当前执行步骤
  116. /// </summary>
  117. private string _currentCCRStep = "";
  118. /// <summary>
  119. /// CCR当前剩余时间
  120. /// </summary>
  121. private double _timeRemain;
  122. /// <summary>
  123. /// 对应reservoir槽体化学液
  124. /// </summary>
  125. private string _reservoirChemistry;
  126. /// <summary>
  127. /// clamshell open sensor config
  128. /// </summary>
  129. private int _openSensor = 55;
  130. /// <summary>
  131. /// clamshell close sensor config
  132. /// </summary>
  133. private int _closeSensor = 5;
  134. #endregion
  135. #region 属性
  136. /// <summary>
  137. /// 状态
  138. /// </summary>
  139. public RState Status { get { return _status; } }
  140. /// <summary>
  141. /// 是否禁用
  142. /// </summary>
  143. public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } }
  144. /// <summary>
  145. /// 操作模式
  146. /// </summary>
  147. public string OperationMode { get { return _persistentValue.OperatingMode; } }
  148. /// <summary>
  149. /// 工程模式
  150. /// </summary>
  151. public string EngineerMode { get { return _persistentValue.RecipeOperatingMode; } }
  152. /// <summary>
  153. /// 是否为Auto
  154. /// </summary>
  155. public bool IsAuto { get { return _persistentValue != null ? _persistentValue.OperatingMode == AUTO : false; } }
  156. /// <summary>
  157. /// 是否为Auto
  158. /// </summary>
  159. public bool IsManual { get { return _persistentValue != null ? _persistentValue.OperatingMode == MANUAL : false; } }
  160. /// <summary>
  161. /// PowerSupplier
  162. /// </summary>
  163. public CellPowerSupplier PowerSupplier { get { return _powerSupplier; } }
  164. #endregion
  165. #region 共享变量
  166. /// <summary>
  167. /// 数据
  168. /// </summary>
  169. protected PlatingCellData _platingCellData = new PlatingCellData();
  170. /// <summary>
  171. /// 对应reservoir数据
  172. /// </summary>
  173. protected ReservoirData _reservoirData = new ReservoirData();
  174. #endregion
  175. #region 共享属性
  176. /// <summary>
  177. /// 设备数据
  178. /// </summary>
  179. public PlatingCellData PlatingCellDeviceData { get { return _platingCellData; } }
  180. #endregion
  181. /// <summary>
  182. /// 构造函数
  183. /// </summary>
  184. /// <param name="moduleName"></param>
  185. public PlatingCellDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)
  186. {
  187. }
  188. /// <summary>
  189. /// 初始化
  190. /// </summary>
  191. /// <returns></returns>
  192. public virtual bool Initialize()
  193. {
  194. InitializeParameter();
  195. SubscribeData();
  196. InitializeOperation();
  197. SubscribeValueAction();
  198. InitializeRoutine();
  199. return true;
  200. }
  201. /// <summary>
  202. /// 初始化Routine
  203. /// </summary>
  204. private void InitializeRoutine()
  205. {
  206. _closeRoutine = new ClamShellCloseRoutine(Module);
  207. _biDirectionRoutine = new RotationBiDirectionRoutine(Module);
  208. }
  209. /// <summary>
  210. /// 定时器执行
  211. /// </summary>
  212. public bool OnTimer(int interval)
  213. {
  214. if (_verticalAxis != null)
  215. {
  216. _verticalAxis.OnTimer();
  217. }
  218. else
  219. {
  220. if ("PlatingCell1".Equals(Module) || "PlatingCell2".Equals(Module))
  221. {
  222. _verticalAxis = DEVICE.GetDevice<JetAxisBase>("PlatingCell1_2.Vertical");
  223. }
  224. else
  225. {
  226. _verticalAxis = DEVICE.GetDevice<JetAxisBase>("PlatingCell3_4.Vertical");
  227. }
  228. }
  229. if (_rotationAxis != null)
  230. {
  231. _rotationAxis.OnTimer();
  232. }
  233. if (_status == RState.Running)
  234. {
  235. if (_currentOperation != PlatingCellCommonOperation.None)
  236. {
  237. IRoutine routine = GetCurrentRoutine(_currentOperation);
  238. if (routine != null)
  239. {
  240. CheckRoutineState(routine, _currentOperation);
  241. }
  242. else
  243. {
  244. EndOperation();
  245. }
  246. }
  247. }
  248. return true;
  249. }
  250. /// <summary>
  251. /// 获取当前操作对应的Routine
  252. /// </summary>
  253. /// <param name="currentOperation"></param>
  254. /// <returns></returns>
  255. private IRoutine GetCurrentRoutine(PlatingCellCommonOperation currentOperation)
  256. {
  257. switch (currentOperation)
  258. {
  259. case PlatingCellCommonOperation.ClamShellOpen:
  260. case PlatingCellCommonOperation.ClamShellClose:
  261. return _closeRoutine;
  262. case PlatingCellCommonOperation.BiRotation:
  263. return _biDirectionRoutine;
  264. default:
  265. return null;
  266. }
  267. }
  268. /// <summary>
  269. /// 检验Routine状态
  270. /// </summary>
  271. /// <param name="routine"></param>
  272. /// <param name="currentOperation"></param>
  273. private void CheckRoutineState(IRoutine routine, PlatingCellCommonOperation currentOperation)
  274. {
  275. RState state = routine.Monitor();
  276. if (state == RState.End)
  277. {
  278. EndOperation();
  279. }
  280. else if (state == RState.Failed || state == RState.Timeout)
  281. {
  282. LOG.WriteLog(eEvent.ERR_SRD, $"{Module}", $"{currentOperation} error");
  283. _status = RState.Failed;
  284. _currentOperation = PlatingCellCommonOperation.None;
  285. }
  286. }
  287. /// <summary>
  288. /// 结束操作
  289. /// </summary>
  290. private void EndOperation()
  291. {
  292. _status = RState.End;
  293. _currentOperation = PlatingCellCommonOperation.None;
  294. }
  295. /// <summary>
  296. /// 初始化参数
  297. /// </summary>
  298. private void InitializeParameter()
  299. {
  300. _persistentValue = PlatingCellPersistentManager.Instance.GetPlatingCellPersistentValue(Module);
  301. if (_persistentValue == null)
  302. {
  303. LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Persistent Value Object is not exist");
  304. }
  305. _platingCellItem = PlatingCellItemManager.Instance.GetPlatingCellItem(Module);
  306. if (_platingCellItem != null)
  307. {
  308. }
  309. _platingCellItem = PlatingCellItemManager.Instance.GetPlatingCellItem(Module);
  310. if (_platingCellItem != null)
  311. {
  312. _powerSupplier = DEVICE.GetDevice<CellPowerSupplier>(_platingCellItem.PlatingPowerSupplyID);
  313. }
  314. _overflowLevelHigh = SC.GetValue<int>($"PlatingCell.OverflowLevelHigh");
  315. _overflowLevelLow = SC.GetValue<int>($"PlatingCell.OverflowLevelLow");
  316. _openSensor = SC.GetValue<int>("PlatingCell.ClamShellOpenDistanceThreshold");
  317. _closeSensor = SC.GetValue<int>("PlatingCell.ClamShellCloseDistanceThreshold");
  318. _reservoirData = GetReservoirDevice().ReservoirData;
  319. _reservoirName = GetReservoirDevice().Module;
  320. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  321. }
  322. protected virtual void SubscribeValueAction()
  323. {
  324. IoSubscribeUpdateVariable(IS_HEAD_TILT);
  325. IoSubscribeUpdateVariable(IS_HEAD_VERTICAL);
  326. IoSubscribeUpdateVariable(CLAMSHELL_DISTANCE);
  327. IoSubscribeUpdateVariable(CLAMSHELL_CYLINDER_PRESSURE);
  328. IoSubscribeUpdateVariable(OVERFLOW_LEVEL);
  329. IoSubscribeUpdateVariable(CLAMSHELL_CLOSE);
  330. IoSubscribeUpdateVariable(HEAD_TILT);
  331. IoSubscribeUpdateVariable(CCR_ENABLE);
  332. IoSubscribeUpdateVariable(RINSE_ENABLE);
  333. }
  334. /// <summary>
  335. /// 订阅IO变量
  336. /// </summary>
  337. /// <param name="variable"></param>
  338. protected void IoSubscribeUpdateVariable(string variable)
  339. {
  340. _variableInitializeDic[variable] = false;
  341. IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
  342. }
  343. /// <summary>
  344. /// 更新变量数值
  345. /// </summary>
  346. /// <param name="variable"></param>
  347. /// <param name="value"></param>
  348. private void UpdateVariableValue(string variable, object value)
  349. {
  350. if (!_platingCellData.IsDataInitialized)
  351. {
  352. _platingCellData.IsDataInitialized = true;
  353. }
  354. PropertyInfo property = _platingCellData.GetType().GetProperty(variable);
  355. if (property != null)
  356. {
  357. property.SetValue(_platingCellData, value);
  358. if (variable == OVERFLOW_LEVEL)
  359. {
  360. double waterLevel = CurrentToWaterLevel(Convert.ToDouble(value));
  361. _platingCellData.OverFlowLevel = waterLevel;
  362. if (_platingCellData.OverFlowLevel >= _overflowLevelHigh)
  363. {
  364. _platingCellData.OverFlowStatus = "High";
  365. }
  366. else if(_platingCellData.OverFlowLevel <= _overflowLevelLow)
  367. {
  368. _platingCellData.OverFlowStatus = "Empty";
  369. }
  370. else
  371. {
  372. _platingCellData.OverFlowStatus = "Full";
  373. }
  374. }
  375. if(variable == CLAMSHELL_DISTANCE)
  376. {
  377. double distance = Convert.ToDouble(value);
  378. if(distance >= _closeSensor)
  379. {
  380. _platingCellData.ClamShellClosed = true;
  381. _platingCellData.ClamShellOpened = false;
  382. }
  383. if(distance <= _openSensor)
  384. {
  385. _platingCellData.ClamShellClosed = false;
  386. _platingCellData.ClamShellOpened = true;
  387. }
  388. }
  389. }
  390. if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
  391. {
  392. _variableInitializeDic[variable] = true;
  393. }
  394. }
  395. /// <summary>
  396. /// 把电流mA转成水深mm
  397. /// </summary>
  398. /// <param name="current"></param>
  399. private double CurrentToWaterLevel(double current)
  400. {
  401. double result = (current - 4) / 8 / 9.8 * 1000;
  402. return result;
  403. }
  404. /// <summary>
  405. /// 写变量
  406. /// </summary>
  407. /// <param name="variable"></param>
  408. /// <param name="value"></param>
  409. /// <returns></returns>
  410. protected bool WriteVariableValue(string variable, object value)
  411. {
  412. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{variable}");
  413. return IOModuleManager.Instance.WriteIoValue(ioName, value);
  414. }
  415. /// <summary>
  416. /// 订阅数据
  417. /// </summary>
  418. private void SubscribeData()
  419. {
  420. DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _persistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  421. DATA.Subscribe($"{Module}.{PLATINGCELLDATA}", () => _platingCellData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  422. DATA.Subscribe($"{Module}.ReservoirCommonData", () => _reservoirData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  423. DATA.Subscribe($"{Module}.ReservoirName", () => _reservoirName, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  424. DATA.Subscribe($"{Module}.CurrentCCRStep", () => _currentCCRStep, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  425. DATA.Subscribe($"{Module}.CurrentCCRTimeRemain", () => _timeRemain, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  426. DATA.Subscribe($"{Module}.ReservoirChemistry", () => _reservoirChemistry, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  427. DATA.Subscribe($"{Module}.PowerSupplierData", () => _powerSupplier.PowerSupplierData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  428. DATA.Subscribe($"{Module}.PowerSupplier.ID", () => _powerSupplier.Module, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  429. DATA.Subscribe($"{Module}.PowerSupplier.IsConnected", () => _powerSupplier.IsConnected, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  430. DATA.Subscribe($"{Module}.PowerSupplier.Voltage", () => _powerSupplier.PowerSupplierData.Voltage, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  431. DATA.Subscribe($"{Module}.PowerSupplier.Current", () => _powerSupplier.PowerSupplierData.Current, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  432. DATA.Subscribe($"{Module}.PowerSupplier.SetPoint", () => _powerSupplier.PowerSupplierData.SetPoint, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  433. DATA.Subscribe($"{Module}.PowerSupplier.RunModel", () => _powerSupplier.PowerSupplierData.PowerRunModelContent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  434. DATA.Subscribe($"{Module}.PowerSupplier.PowerControl", () => _powerSupplier.PowerSupplierData.PowerControlContent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  435. DATA.Subscribe($"{Module}.PowerSupplier.PowerStatus", () => _powerSupplier.PowerSupplierData.PowerStatusContent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  436. DATA.Subscribe($"{Module}.PowerSupplier.Enable", () => _powerSupplier.PowerSupplierData.Enabled, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  437. DATA.Subscribe($"{Module}.PowerSupplier.PowerGrade", () => _powerSupplier.PowerSupplierData.PowerGradeContent, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  438. }
  439. /// <summary>
  440. /// 初始化操作
  441. /// </summary>
  442. protected virtual void InitializeOperation()
  443. {
  444. OP.Subscribe($"{Module}.DisabledAction", DisabledOperation);
  445. OP.Subscribe($"{Module}.ManualAction", ManualOperation);
  446. OP.Subscribe($"{Module}.AutoAction", AutoOperation);
  447. OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation);
  448. OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation);
  449. OP.Subscribe($"{Module}.SetPlatingCellWaferSize", (cmd, args) => { return SetPlatingCellWaferSize(cmd, args); });
  450. OP.Subscribe($"{Module}.ClamShellClose", (cmd, para) => { return ClamShellClose(); });
  451. OP.Subscribe($"{Module}.ClamShellOpen", (cmd, para) => { return ClamShellOpen(); });
  452. OP.Subscribe($"{Module}.HeadtTilt", (cmd, para) => { return HeadtTiltAction(); });
  453. OP.Subscribe($"{Module}.HeadVertical", (cmd, para) => { return HeadtVerticalAction(); });
  454. OP.Subscribe($"{Module}.CCREnable", (cmd, para) => { return CCREnableAction(); });
  455. OP.Subscribe($"{Module}.CCRDisable", (cmd, para) => { return CCRDisableAction(); });
  456. OP.Subscribe($"{Module}.RinseEnable", (cmd, para) => { return RinseEnableAction(); });
  457. OP.Subscribe($"{Module}.RinseDisable", (cmd, para) => { return RinseDisableAction(); });
  458. OP.Subscribe($"{Module}.StartRotation", StartRotationAction);
  459. OP.Subscribe($"{Module}.StopRotation", StopRotationAction);
  460. OP.Subscribe($"{Module}.StartBiRotation", StartBiRotationAction);
  461. }
  462. #region Operation
  463. private bool StartRotationAction(string cmd, object[] args)
  464. {
  465. if (args.Length < 2 && (int)args[0] < 0 && (int)args[1] < 0)
  466. {
  467. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"Start rotation paramater is wrong");
  468. return false;
  469. }
  470. double targetPostion = (int)args[0] * 6 * (int)args[1];
  471. object[] param = new object[] { "", targetPostion };
  472. int degSpeed = (int)args[0] * 6;
  473. SetRotationSpeed(degSpeed);
  474. double AfterChangetargetPostion = (int)args[0] * 6 * (int)args[1];
  475. return RotationProfilePosition(AfterChangetargetPostion);
  476. }
  477. private bool StartBiRotationAction(string cmd, object[] args)
  478. {
  479. int _rotationTime = (int)args[0];
  480. int _frequency = (int)args[1];
  481. int _speed = (int)args[2];
  482. if (!JudgeRunningState(PlatingCellCommonOperation.BiRotation))
  483. {
  484. _currentOperation = PlatingCellCommonOperation.BiRotation;
  485. _status = _biDirectionRoutine.Start(_rotationTime, _frequency, _speed);
  486. return _status == RState.Running;
  487. }
  488. else
  489. {
  490. return false;
  491. }
  492. }
  493. private bool StopRotationAction(string cmd, object[] args)
  494. {
  495. return _rotationAxis.StopPositionOperation();
  496. }
  497. //public bool ClamShellClose()
  498. //{
  499. // return WriteVariableValue(CLAMSHELL_CLOSE, true);
  500. //}
  501. //public bool ClamShellOpen()
  502. //{
  503. // return WriteVariableValue(CLAMSHELL_CLOSE, false);
  504. //}
  505. public bool HeadtTiltAction()
  506. {
  507. return WriteVariableValue(HEAD_TILT, true);
  508. }
  509. public bool HeadtVerticalAction()
  510. {
  511. return WriteVariableValue(HEAD_TILT, false);
  512. }
  513. public bool CCREnableAction()
  514. {
  515. return WriteVariableValue(CCR_ENABLE, true);
  516. }
  517. public bool CCRDisableAction()
  518. {
  519. return WriteVariableValue(CCR_ENABLE, false);
  520. }
  521. public bool RinseEnableAction()
  522. {
  523. return WriteVariableValue(RINSE_ENABLE, true);
  524. }
  525. public bool RinseDisableAction()
  526. {
  527. return WriteVariableValue(RINSE_ENABLE, false);
  528. }
  529. #region ClamShell Close
  530. /// <summary>
  531. /// ClamShell Close
  532. /// </summary>
  533. /// <param name="cmd"></param>
  534. /// <param name="args"></param>
  535. /// <returns></returns>
  536. public bool ClamShellClose()
  537. {
  538. if (!JudgeRunningState(PlatingCellCommonOperation.ClamShellClose))
  539. {
  540. _currentOperation = PlatingCellCommonOperation.ClamShellClose;
  541. _status = _closeRoutine.Start(true);
  542. return _status == RState.Running;
  543. }
  544. else
  545. {
  546. return false;
  547. }
  548. }
  549. /// <summary>
  550. /// ClamShell Open
  551. /// </summary>
  552. /// <param name="cmd"></param>
  553. /// <param name="args"></param>
  554. /// <returns></returns>
  555. public bool ClamShellOpen()
  556. {
  557. if (!JudgeRunningState(PlatingCellCommonOperation.ClamShellOpen))
  558. {
  559. _currentOperation = PlatingCellCommonOperation.ClamShellOpen;
  560. _status = _closeRoutine.Start(false);
  561. return _status == RState.Running;
  562. }
  563. else
  564. {
  565. return false;
  566. }
  567. }
  568. /// <summary>
  569. /// 判定运行状态
  570. /// </summary>
  571. /// <returns></returns>
  572. private bool JudgeRunningState(PlatingCellCommonOperation operation)
  573. {
  574. if (_status == RState.Running)
  575. {
  576. EV.PostAlarmLog($"{Module}", eEvent.ERR_PLATINGCELL, $"{Module} current execute {_currentOperation},cannot {operation}");
  577. return true;
  578. }
  579. return false;
  580. }
  581. #endregion
  582. /// <summary>
  583. /// DisabledAction
  584. /// </summary>
  585. /// <param name="cmd"></param>
  586. /// <param name="param"></param>
  587. /// <returns></returns>
  588. public bool DisabledOperation(string cmd, object[] args)
  589. {
  590. string currentOperation = "Disabled";
  591. PlatingCellEntity platingCellEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(Module);
  592. if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation)
  593. {
  594. string preOperation = _persistentValue.OperatingMode;
  595. if (platingCellEntity.IsBusy)
  596. {
  597. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{Module} is Busy, can't switch to Disabled mode");
  598. return false;
  599. }
  600. //if (SchedulerMetalTimeManager.Instance.Contained(Module))
  601. //{
  602. // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is in scheduler, can't switch to Disabled mode");
  603. // return false;
  604. //}
  605. platingCellEntity.EnterInit();
  606. _persistentValue.OperatingMode = currentOperation;
  607. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
  608. }
  609. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  610. return true;
  611. }
  612. /// <summary>
  613. /// ManualAction
  614. /// </summary>
  615. /// <param name="cmd"></param>
  616. /// <param name="param"></param>
  617. /// <returns></returns>
  618. public bool ManualOperation(string cmd, object[] args)
  619. {
  620. string currentOperation = "Manual";
  621. PlatingCellEntity platingCellEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(Module);
  622. if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation)
  623. {
  624. string preOperation = _persistentValue.OperatingMode;
  625. if (platingCellEntity.IsBusy)
  626. {
  627. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{Module} is Busy, can't switch to Manual mode");
  628. return false;
  629. }
  630. //if (SchedulerMetalTimeManager.Instance.Contained(Module))
  631. //{
  632. // LOG.WriteLog(eEvent.ERR_METAL, Module, $"{Module} is in scheduler, can't switch to Manual mode");
  633. // return false;
  634. //}
  635. platingCellEntity.EnterInit();
  636. _persistentValue.OperatingMode = currentOperation;
  637. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
  638. }
  639. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  640. return true;
  641. }
  642. /// <summary>
  643. /// AutoAction
  644. /// </summary>
  645. /// <param name="cmd"></param>
  646. /// <param name="param"></param>
  647. /// <returns></returns>
  648. public bool AutoOperation(string cmd, object[] args)
  649. {
  650. string currentOperation = "Auto";
  651. ReservoirEntity reservoirEntity = Singleton<RouteManager>.Instance.GetModule<ReservoirEntity>(_reservoirName);
  652. if (reservoirEntity!=null && reservoirEntity.PersistentValue.OperatingMode!="Auto")
  653. {
  654. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{_reservoirName} not in Auto mode, can't switch to Auto mode");
  655. return false;
  656. }
  657. PlatingCellEntity platingCellEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(Module);
  658. if (platingCellEntity != null && _persistentValue != null && _persistentValue.OperatingMode != currentOperation)
  659. {
  660. string preOperation = _persistentValue.OperatingMode;
  661. if (platingCellEntity.IsBusy)
  662. {
  663. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{Module} is Busy, can't switch to Auto mode");
  664. return false;
  665. }
  666. platingCellEntity.EnterInit();
  667. _persistentValue.OperatingMode = currentOperation;
  668. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");
  669. }
  670. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  671. return true;
  672. }
  673. /// <summary>
  674. /// EngineeringModeAction
  675. /// </summary>
  676. /// <param name="cmd"></param>
  677. /// <param name="param"></param>
  678. /// <returns></returns>
  679. private bool EngineeringModeOperation(string cmd, object[] args)
  680. {
  681. string currentRecipeOperation = "Engineering";
  682. if (_persistentValue != null)
  683. {
  684. _persistentValue.RecipeOperatingMode = currentRecipeOperation;
  685. }
  686. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  687. return true;
  688. }
  689. /// <summary>
  690. /// ProductionAction
  691. /// </summary>
  692. /// <param name="cmd"></param>
  693. /// <param name="param"></param>
  694. /// <returns></returns>
  695. private bool ProductionModeOperation(string cmd, object[] args)
  696. {
  697. string currentRecipeOperation = "Production";
  698. if (_persistentValue != null)
  699. {
  700. _persistentValue.RecipeOperatingMode = currentRecipeOperation;
  701. }
  702. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  703. return true;
  704. }
  705. private bool SetPlatingCellWaferSize(string cmd, object[] args)
  706. {
  707. string metalWaferSize = args[0] as string;
  708. if (_persistentValue != null)
  709. {
  710. _persistentValue.PlatingCellWaferSize = int.Parse(metalWaferSize);
  711. }
  712. PlatingCellPersistentManager.Instance.UpdatePersistentValue(Module);
  713. return true;
  714. }
  715. /// <summary>
  716. /// 获取Reservoir设备
  717. /// </summary>
  718. /// <returns></returns>
  719. private ReservoirDevice GetReservoirDevice()
  720. {
  721. string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module);
  722. return DEVICE.GetDevice<ReservoirDevice>(reservoir);
  723. }
  724. /// <summary>
  725. /// CCR当前步骤
  726. /// </summary>
  727. /// <param name="tmp"></param>
  728. public void UpdateStatus(string tmp)
  729. {
  730. _currentCCRStep = tmp;
  731. }
  732. /// <summary>
  733. /// CCR当前步骤剩余时间
  734. /// </summary>
  735. /// <param name="tmp"></param>
  736. public void UpdateCCRTimeRemain(double timeRemain)
  737. {
  738. _timeRemain = timeRemain;
  739. }
  740. #endregion
  741. #region RotationAxis
  742. /// <summary>
  743. /// 电机是否上电
  744. /// </summary>
  745. /// <returns></returns>
  746. public bool CheckRotationSwitchOn()
  747. {
  748. return _rotationAxis.IsSwitchOn;
  749. }
  750. /// <summary>
  751. /// Home rotation
  752. /// </summary>
  753. /// <returns></returns>
  754. public bool HomeRotation()
  755. {
  756. return _rotationAxis.Home();
  757. }
  758. /// <summary>
  759. /// 检验Rotation Home结果
  760. /// </summary>
  761. /// <returns></returns>
  762. public bool CheckHomeEndStatus()
  763. {
  764. return CheckRotationEndStatus() && _rotationAxis.IsHomed;
  765. }
  766. /// <summary>
  767. /// 检验Rotation结束状态
  768. /// </summary>
  769. /// <returns></returns>
  770. public bool CheckRotationEndStatus()
  771. {
  772. return _rotationAxis.Status == PunkHPX8_Core.RState.End;
  773. }
  774. /// <summary>
  775. /// 检验Rotation失败状态
  776. /// </summary>
  777. /// <returns></returns>
  778. public bool CheckRotationStopStatus()
  779. {
  780. return _rotationAxis.Status == PunkHPX8_Core.RState.Failed;
  781. }
  782. /// <summary>
  783. /// 设置速度
  784. /// </summary>
  785. /// <param name="speed"></param>
  786. /// <returns></returns>
  787. public bool SetRotationSpeed(int speed)
  788. {
  789. _rotationAxis.SetProfileSpeed(speed);
  790. return true;
  791. }
  792. /// <summary>
  793. /// 改变速度
  794. /// </summary>
  795. /// <param name="speed"></param>
  796. /// <returns></returns>
  797. public bool ChangeRotationSpeed(int speed)
  798. {
  799. return _rotationAxis.ChangeSpeed(speed);
  800. }
  801. /// <summary>
  802. /// 电机运动
  803. /// </summary>
  804. /// <param name="position"></param>
  805. /// <returns></returns>
  806. public bool RotationProfilePosition(double position)
  807. {
  808. return _rotationAxis.ProfilePositionOperation(position);
  809. }
  810. /// <summary>
  811. /// 停止运动
  812. /// </summary>
  813. /// <returns></returns>
  814. public bool StopProfilePosition()
  815. {
  816. return _rotationAxis.StopPositionOperation();
  817. }
  818. /// <summary>
  819. /// 是否Rotation运动
  820. /// </summary>
  821. /// <returns></returns>
  822. public bool CheckRotationRunning()
  823. {
  824. return _rotationAxis.IsRun;
  825. }
  826. #endregion
  827. public virtual void Monitor()
  828. {
  829. }
  830. public virtual void Reset()
  831. {
  832. }
  833. public virtual void Terminate()
  834. {
  835. }
  836. }
  837. }