PlatingCellDevice.cs 31 KB

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