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 内部变量
///
/// ModuleName
///
private string _moduleName;
///
/// ReplenName
///
private string _replenName;
///
/// ReplenID
///
private int _replenId;
///
/// ReservoirDosingRoutine
///
private ReservoirDosingRoutine _reservoirDosingRoutine;
///
/// 当前加载Recipoe
///
private RdsRecipe _currentRecipe;
///
/// 当次自动补液体积
///
private double _autoDosingVolume;
///
/// 最小补液体积
///
private double _minDoseAmount;
///
/// Replen Persistent
///
private ReplenPersistentValue _persistentValue;
///
/// Reservoir Usage
///
private ReservoirUsage _reservoirUsage;
#endregion
#region 属性
///
/// 当次自动补液体积
///
public double AutoDosingVolume { get { return _autoDosingVolume; } }
///
/// Dosing状态
///
public RState DosingState { get { return _reservoirDosingRoutine.Monitor(); } }
#endregion
///
/// 构造函数
///
///
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
///
/// 开始Dosing
///
public bool StartDosing(double targetVolume, bool isAutoMode)
{
_persistentValue.IsDosingRunning = true;
ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
return _reservoirDosingRoutine.Start(targetVolume, isAutoMode) == RState.Running;
}
///
/// 停止Dosing
///
public bool StopDosing()
{
_persistentValue.IsDosingRunning = false;
ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
_reservoirDosingRoutine.Abort();
return true;
}
///
/// Dosing超时监控
///
///
public bool DosingTimeOutMonitor()
{
RState result = _reservoirDosingRoutine.Monitor();
if(result == RState.Failed || result == RState.Timeout)
{
return false;
}
return true;
}
///
/// 监控AutoDose触发时机
///
///
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($"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;
}
///
/// 检查并加载Recipe
///
///
///
public bool CheckandLoadRecipe(RdsRecipe recipe)
{
if (_currentRecipe == recipe)
{
return true;
}
else if (_currentRecipe == null)
{
_currentRecipe = recipe;
return true;
}
else
{
_currentRecipe = recipe;
return false;
}
}
///
/// 记录AutoDosing开始时的时间和电量
///
public void RecordStartData()
{
_reservoirUsage = ReservoirUsageManager.Instance.GetReservoirUsage(_moduleName);
_persistentValue.AutoDosingStartTime = DateTime.Now;
if(_reservoirUsage != null) _persistentValue.AutoDosingStartAmpHour = _reservoirUsage.TotalUsage;
ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
}
///
/// 设置PumpFactor
///
public void SetPumpfactor(double targetPumpFactor)
{
_persistentValue.ReplenPumpFactor = targetPumpFactor;
ReplenPersistentManager.Instance.UpdatePersistentValue(_moduleName, _replenName);
}
#endregion
}
}