PlatingCellDevice.cs 32 KB

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