CrossDoseHelper.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using PunkHPX8_Core;
  7. using PunkHPX8_RT.Devices.Dose;
  8. using PunkHPX8_RT.Modules;
  9. using PunkHPX8_RT.Modules.Reservoir;
  10. using MECF.Framework.Common.Beckhoff.ModuleIO;
  11. using MECF.Framework.Common.IOCore;
  12. using MECF.Framework.Common.Persistent.Reservoirs;
  13. using MECF.Framework.Common.ProcessCell;
  14. using MECF.Framework.Common.RecipeCenter;
  15. using MECF.Framework.Common.ToolLayout;
  16. using MECF.Framework.Common.TwinCat;
  17. using System;
  18. using System.Reflection;
  19. using System.Windows;
  20. using static PunkHPX8_RT.Devices.Reservoir.DosingSystemHelper;
  21. namespace PunkHPX8_RT.Devices.Reservoir
  22. {
  23. public class CrossDoseHelper
  24. {
  25. #region 常量
  26. public enum CrossDoseOperation
  27. {
  28. None,
  29. ManualDosing,
  30. AutoDosing,
  31. }
  32. /// <summary>
  33. /// 补液体积(固定10mL)
  34. /// </summary>
  35. private const double DOSING_VOLUME = 10;
  36. #endregion
  37. #region 内部变量
  38. /// <summary>
  39. /// ModuleName
  40. /// </summary>
  41. private string _moduleName;
  42. /// <summary>
  43. /// CrossDoseResetRoutine
  44. /// </summary>
  45. private CrossDoseResetRoutine _crossDoseResetRoutine;
  46. /// <summary>
  47. /// ReservoirsPersistentValue
  48. /// </summary>
  49. private ReservoirsPersistentValue _persistentValue;
  50. /// <summary>
  51. /// CrossDoseVolume
  52. /// </summary>
  53. private double _crossDoseVolume;
  54. /// <summary>
  55. /// 当前CrossDose模式
  56. /// </summary>
  57. private CrossDoseOperation _currentCrossDoseOperation;
  58. /// <summary>
  59. /// Reservoir Usage
  60. /// </summary>
  61. private ReservoirUsage _reservoirUsage;
  62. private bool _flag;
  63. #endregion
  64. #region 属性
  65. /// <summary>
  66. /// 当前Dose模式
  67. /// </summary>
  68. public CrossDoseOperation CurrentDoseOperation{ get {return _currentCrossDoseOperation; } }
  69. /// <summary>
  70. /// ResetRoutine当前的RState
  71. /// </summary>
  72. public RState ResetState { get { return _crossDoseResetRoutine.CurrentState; } }
  73. #endregion
  74. public CrossDoseHelper(string moduleName)
  75. {
  76. _moduleName = moduleName;
  77. _crossDoseResetRoutine = new CrossDoseResetRoutine(_moduleName);
  78. _persistentValue = ReservoirsPersistentManager.Instance.GetReservoirsPersistentValue(_moduleName);
  79. _currentCrossDoseOperation = CrossDoseOperation.None;
  80. }
  81. #region Operation
  82. /// <summary>
  83. /// 开始Dosing
  84. /// </summary>
  85. /// <returns></returns>
  86. public bool StartDosing(double crossDoseVolume)
  87. {
  88. return false;
  89. }
  90. /// <summary>
  91. /// 停止Dosing
  92. /// </summary>
  93. /// <returns></returns>
  94. public bool HaltDosing()
  95. {
  96. EnterError();
  97. return true;
  98. }
  99. /// <summary>
  100. /// CrossDosing监控
  101. /// </summary>
  102. public void CrossDoseStatusMonitor()
  103. {
  104. }
  105. /// <summary>
  106. /// 自动CrossDose监控
  107. /// </summary>
  108. public void AutoCrossDoseMonitor(bool isInitialized)
  109. {
  110. if (!isInitialized)
  111. {
  112. if (!_flag)
  113. {
  114. LOG.WriteLog(eEvent.WARN_RESERVOIR, _moduleName, "Please initialize Cross Dose");
  115. _flag = true;
  116. }
  117. return;
  118. }
  119. _flag = false;
  120. }
  121. /// <summary>
  122. /// 自动补液触发时机判断
  123. /// </summary>
  124. /// <returns></returns>
  125. private bool AutoDosingMonitor()
  126. {
  127. return true;
  128. }
  129. /// <summary>
  130. /// 设置手动Dose模式
  131. /// </summary>
  132. public void SetManualDoseOperation()
  133. {
  134. _currentCrossDoseOperation = CrossDoseOperation.ManualDosing;
  135. }
  136. /// <summary>
  137. /// 设置自动Dose模式
  138. /// </summary>
  139. public void SetAutoDoseOperation()
  140. {
  141. _currentCrossDoseOperation = CrossDoseOperation.AutoDosing;
  142. }
  143. /// <summary>
  144. /// 重置Dose模式
  145. /// </summary>
  146. public void ResetDoseOperation()
  147. {
  148. _currentCrossDoseOperation = CrossDoseOperation.None;
  149. }
  150. /// <summary>
  151. /// EnterError
  152. /// </summary>
  153. private bool EnterError()
  154. {
  155. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpExecute");
  156. bool result = IOModuleManager.Instance.WriteIoValue(ioName, false);
  157. if (!result)
  158. {
  159. return false;
  160. }
  161. ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{_moduleName}.TransferPumpEnable");
  162. result = IOModuleManager.Instance.WriteIoValue(ioName, false);
  163. if (!result)
  164. {
  165. return false;
  166. }
  167. return true;
  168. }
  169. /// <summary>
  170. /// 记录AutoCrossDose开始时的时间和电量
  171. /// </summary>
  172. private void RecordStartData()
  173. {
  174. _reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(_moduleName);
  175. _persistentValue.AutoCrossDoseStartTime = DateTime.Now;
  176. if (_reservoirUsage != null) _persistentValue.AutoCrossDoseStartAmpHour = _reservoirUsage.TotalUsage;
  177. ReservoirsPersistentManager.Instance.UpdatePersistentValue(_moduleName);
  178. }
  179. /// <summary>
  180. /// 设置PumpFactor
  181. /// </summary>
  182. public void SetPumpfactor(double targetPumpFactor)
  183. {
  184. _persistentValue.CrossDosePumpFactor = targetPumpFactor;
  185. ReservoirsPersistentManager.Instance.UpdatePersistentValue(_moduleName);
  186. }
  187. /// <summary>
  188. /// Reset Start
  189. /// </summary>
  190. public bool ResetCrossDose()
  191. {
  192. return _crossDoseResetRoutine.Start() == RState.Running;
  193. }
  194. /// <summary>
  195. /// Reset Start Monitor
  196. /// </summary>
  197. /// <returns></returns>
  198. public bool ResetCrossDoseMonitor()
  199. {
  200. RState result = _crossDoseResetRoutine.Monitor();
  201. if (result == RState.Failed || result == RState.Timeout)
  202. {
  203. LOG.WriteLog(eEvent.WARN_RESERVOIR, _moduleName, "Reset Cross Dose failed");
  204. return false;
  205. }
  206. return result == RState.End;
  207. }
  208. #endregion
  209. }
  210. }