123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using CyberX8_Core;
- using CyberX8_RT.Modules.Reservoir;
- using CyberX8_RT.Modules.SRD;
- using MECF.Framework.Common.Beckhoff.ModuleIO;
- using MECF.Framework.Common.Persistent.Reservoirs;
- using MECF.Framework.Common.Persistent.Temperature;
- using MECF.Framework.Common.ProcessCell;
- using MECF.Framework.Common.RecipeCenter;
- using MECF.Framework.Common.ToolLayout;
- using MECF.Framework.Common.TwinCat;
- using System;
- using System.Net;
- using System.Reflection;
- namespace CyberX8_RT.Devices.Reservoir
- {
- public class DosingSystemHelper
- {
- #region 常量
- public enum BottleLevelState
- {
- Empty,
- Full,
- Warning,
- }
-
- public enum DosingOperation
- {
- None,
- ManualDosing,
- AutoDosing,
- }
- #endregion
- #region 内部变量
- /// <summary>
- /// ModuleName
- /// </summary>
- private string _moduleName;
- /// <summary>
- /// ReplenName
- /// </summary>
- private string _replenName;
- /// <summary>
- /// ReplenID
- /// </summary>
- private int _replenId;
- /// <summary>
- /// ReservoirDosingRoutine
- /// </summary>
- private ReservoirDosingRoutine _reservoirDosingRoutine;
- /// <summary>
- /// 当前加载Recipoe
- /// </summary>
- private RdsRecipe _currentRecipe;
- /// <summary>
- /// 当次自动补液体积
- /// </summary>
- private double _autoDosingVolume;
- /// <summary>
- /// 最小补液体积
- /// </summary>
- private double _minDoseAmount;
- /// <summary>
- /// Replen Persistent
- /// </summary>
- private ReplenPersistentValue _persistentValue;
- /// <summary>
- /// Reservoir Usage
- /// </summary>
- private ReservoirUsage _reservoirUsage;
- #endregion
- #region 属性
- /// <summary>
- /// 当次自动补液体积
- /// </summary>
- public double AutoDosingVolume { get { return _autoDosingVolume; } }
- /// <summary>
- /// Dosing状态
- /// </summary>
- public RState DosingState { get { return _reservoirDosingRoutine.Monitor(); } }
-
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="moduleName"></param>
- public DosingSystemHelper(string moduleName, string replenName)
- {
- _moduleName = moduleName;
- _replenName = replenName;
- _replenId = int.Parse(replenName.Substring(6, 1));
- _persistentValue = ReplenPersistentManager.Instance.GetReplenPersistentValue(_moduleName, _replenName);
- _reservoirDosingRoutine = new ReservoirDosingRoutine(_moduleName,_replenName);
-
- }
- #region Operation
- /// <summary>
- /// 开始Dosing
- /// </summary>
- public bool StartDosing(double targetVolume, bool isAutoMode)
- {
- _persistentValue.IsDosingRunning = true;
- ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
- return _reservoirDosingRoutine.Start(targetVolume, isAutoMode) == RState.Running;
- }
- /// <summary>
- /// 停止Dosing
- /// </summary>
- public bool StopDosing()
- {
- _persistentValue.IsDosingRunning = false;
- ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
- _reservoirDosingRoutine.Abort();
- return true;
- }
- /// <summary>
- /// Dosing超时监控
- /// </summary>
- /// <returns></returns>
- public bool DosingTimeOutMonitor()
- {
- RState result = _reservoirDosingRoutine.Monitor();
- if(result == RState.Failed || result == RState.Timeout)
- {
- return false;
- }
- return true;
- }
- /// <summary>
- /// 监控AutoDose触发时机
- /// </summary>
- /// <returns></returns>
- public bool AutoDosingMonitor()
- {
- bool result = false;
- double targetVolume = 0;
- double currentDosingAmpHour = 0;
- _reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(_moduleName);
- //最小补液体积
- if (SC.ContainsItem($"Reservoir.{_moduleName}.InitialDosingSpeed"))
- {
- _minDoseAmount = SC.GetValue<double>($"Reservoir.{_moduleName}.MinDoseAmount");
- }
- //当前电量
- if(_reservoirUsage != null) currentDosingAmpHour = _reservoirUsage.TotalUsage;
- //累计电量(Ah)
- double deltAmpHour = currentDosingAmpHour - _persistentValue.AutoDosingStartAmpHour;
- //累计时间(hr)
- double deltHour = DateTime.Now.Subtract(_persistentValue.AutoDosingStartTime).TotalHours;
- if (_currentRecipe != null)
- {
- if (_currentRecipe.ReplenEnable)
- {
- if (_currentRecipe.ReplenCurrentBased)
- {
- //基于电量计算DoseVolume
- targetVolume = deltAmpHour * _currentRecipe.ReplenCurrentBasedRate;
- _persistentValue.TargetDosingVolume = Math.Round(targetVolume, 2);
- //计算DoseVolume大于MinDoseAmount则开始补液
- if (targetVolume > _minDoseAmount)
- {
- _autoDosingVolume = targetVolume;
- result = true;
- }
- }
- else if(_currentRecipe.ReplenTimeBased)
- {
- //基于时间计算DoseVolume
- targetVolume = deltHour / 24 * _currentRecipe.ReplenTimeBasedRate;
- _persistentValue.TargetDosingVolume = Math.Round(targetVolume, 2);
- //计算DoseVolume大于MinDoseAmount则开始补液
- if (targetVolume > _minDoseAmount)
- {
- _autoDosingVolume = targetVolume;
- result = true;
- }
- }
- }else if (_currentRecipe.AutoDoseEnable)
- {
- _persistentValue.TargetDosingVolume = _minDoseAmount;
-
- if (_currentRecipe.AutoCurrentBased)
- {
- //累计电量大于AutoDosingStartAmpHour则开始补液
- targetVolume = _minDoseAmount / _currentRecipe.AutoDoseFrequency * deltAmpHour;
- _persistentValue.TargetDosingVolume = Math.Round(targetVolume, 2);
- if (deltAmpHour > _currentRecipe.AutoDoseFrequency)
- {
- result = true;
- _autoDosingVolume = _minDoseAmount;
- }
- }
- else if (_currentRecipe.AutoTimeBased)
- {
- //累计时间大于AutoDoseIdleStartTime则开始补液
- targetVolume = _minDoseAmount / _currentRecipe.AutoDoseIdleStartTime * deltHour;
- _persistentValue.TargetDosingVolume = Math.Round(targetVolume, 2);
- if (deltHour > _currentRecipe.AutoDoseIdleStartTime)
- {
- result = true;
- _autoDosingVolume = _minDoseAmount;
- }
- }
-
- }
-
- }
- ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
- return result;
- }
- /// <summary>
- /// 检查并加载Recipe
- /// </summary>
- /// <param name="recipe"></param>
- /// <returns></returns>
- public bool CheckandLoadRecipe(RdsRecipe recipe)
- {
- if (_currentRecipe == recipe)
- {
- return true;
- }
- else if (_currentRecipe == null)
- {
- _currentRecipe = recipe;
- return true;
- }
- else
- {
- _currentRecipe = recipe;
- return false;
- }
- }
- /// <summary>
- /// 记录AutoDosing开始时的时间和电量
- /// </summary>
- public void RecordStartData()
- {
- _reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(_moduleName);
- _persistentValue.AutoDosingStartTime = DateTime.Now;
- if(_reservoirUsage != null) _persistentValue.AutoDosingStartAmpHour = _reservoirUsage.TotalUsage;
- ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
- }
- /// <summary>
- /// 设置PumpFactor
- /// </summary>
- public void SetPumpfactor(double targetPumpFactor)
- {
- _persistentValue.ReplenPumpFactor = targetPumpFactor;
- ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
- }
-
- #endregion
-
- }
- }
|