Compare commits

...

2 Commits

Author SHA1 Message Date
HCL 94397e770a Merge remote-tracking branch 'origin/V94和V96,打开或关闭时,操作对应MFC' into develop 2023-06-20 11:04:27 +08:00
hanqiangqiang e134a424d1 [RT.EquipmentLibrary]
1V94和V96,打开或关闭时,操作对应MFC
2添加到远程分支,未合并到develope分支
2023-06-19 14:51:19 +08:00
1 changed files with 147 additions and 7 deletions

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.DataCenter;
@ -10,7 +9,6 @@ using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK;
namespace Aitex.Core.RT.Device.Devices
{
@ -21,6 +19,15 @@ namespace Aitex.Core.RT.Device.Devices
public class IoValve : BaseDevice, IDevice, IValve
{
private readonly DeviceTimer _timMfcRampTimeout = new DeviceTimer();
private const int MFC_RAMP_DURATION_SEC = 5;
private const int MFC_RAMP_TIMEOUT_SEC = 10;
private readonly object _mfcLock = new object();
private IoMFC _mappedMfc;
private bool _isValveOnAfterMfcRamp;
public string GVName { get { return Name; } }
public string GVDeviceID { get { return DeviceID; } }
@ -102,6 +109,7 @@ namespace Aitex.Core.RT.Device.Devices
/// </summary>
public bool _isNc;
/// <summary>
/// default open
/// </summary>
@ -187,6 +195,16 @@ namespace Aitex.Core.RT.Device.Devices
public void Terminate()
{
string reason;
lock (_mfcLock)
{
if (_mappedMfc != null)
{
_mappedMfc.StopRamp();
_mappedMfc = null;
_timMfcRampTimeout.Stop();
}
}
TurnValve(_isDefaultOpen, out reason);
}
@ -199,7 +217,10 @@ namespace Aitex.Core.RT.Device.Devices
string name = op ? "Open" : "Close";
if (!TurnValve(op, out reason))
{
EV.PostWarningLog(Module, $"Can not {name} valve {Module}.{Name}, {reason}");
return false;
}
EV.PostInfoLog(Module, $"{name} valve {Module}.{Name}");
@ -225,6 +246,8 @@ namespace Aitex.Core.RT.Device.Devices
}
}
MonitorMfc();
if (_timer.IsTimeout())
{
forceOpenTrigger.RST = true;
@ -304,14 +327,20 @@ namespace Aitex.Core.RT.Device.Devices
public bool TurnValve(bool isOn, out string reason)
{
reason = "";
bool bValue = _isNc ? isOn : !isOn;
var stringOnOff = isOn ? "On" : "Off";
// 如果要打开阀门,并且阀门已经在打开状态,则啥也不干
if (isOn && Status)
{
return true;
}
if (_doOpen != null)
{
if (!_doOpen.Check(bValue, out reason))
{
EV.PostWarningLog(Module, $"Turn {Display} {stringOnOff} failed for Interlock!");
EV.PostWarningLog(Module, $"Turn {Display} {ValveStateToString(isOn)} failed for Interlock!");
EV.PostMessage(Module, EventEnum.SwInterlock, Module, string.Format("Valve {0} was {1}Reason{2}", Display, "Open", reason));
return false;
}
@ -320,7 +349,7 @@ namespace Aitex.Core.RT.Device.Devices
{
if (!FuncCheckInterLock(isOn))
{
EV.PostWarningLog(Module, $"Turn {Display} {stringOnOff} failed for check condition!");
EV.PostWarningLog(Module, $"Turn {Display} {ValveStateToString(isOn)} failed for check condition!");
return false;
}
}
@ -334,7 +363,28 @@ namespace Aitex.Core.RT.Device.Devices
}
}
EV.PostInfoLog(Module, $"Turn {Display} {stringOnOff}");
if (ValveToMFCMap.ValveControlMFC.TryGetValue(Name, out var _mfcName)) // 需要Ramp前置MFC
{
if (!isOn)//关闭蝶阀时关闭MFC,如果MFC为0时可以不用设置但是没有获取MFC当前状态的函数
{
if (_doOpen.Value)//气阀是开启状态了需要关闭MFC
{
CloseMFC(isOn, _mfcName);
return true;
}
}
else//这是开阀指令开阀时如果阀门时关闭状态MFC设置为零保证气流平缓
{
if (Name != "TMVent" && !_doOpen.Value)//气阀是关闭状态了需要关闭MFC
{
CloseMFC(isOn, _mfcName);
return true;
}
}
}
EV.PostInfoLog(Module, $"Turn {Display} {ValveStateToString(isOn)}");
reason = "";
SetPoint = isOn;
@ -343,14 +393,104 @@ namespace Aitex.Core.RT.Device.Devices
_timer.Start(2000); //2 seconds to monitor
return true;
}
/// <summary>
/// 如果存在前置MFC则等待MFC流量到0后再开关阀。
/// </summary>
private void MonitorMfc()
{
lock (_mfcLock)
{
if (_mappedMfc != null)
{
if (_mappedMfc.FeedBack < _mappedMfc.Scale * 0.015) // 等待MFC Ramp到0
{
SetPoint = _isValveOnAfterMfcRamp;
_operation = _isValveOnAfterMfcRamp;
_mappedMfc = null;
_timMfcRampTimeout.Stop();
_timer.Start(2000);
}
else if (_timMfcRampTimeout.IsTimeout()) // 等待MFC Ramp 到0超时
{
_mappedMfc.StopRamp();
_timMfcRampTimeout.Stop();
EV.PostAlarmLog(Module,
$"Timeout to ramp {_mappedMfc.Name} to 0.0{_mappedMfc.Unit} when Turning {Name} {ValveStateToString(_isValveOnAfterMfcRamp)}");
_mappedMfc = null;
}
}
}
}
/// <summary>
/// 关闭前置MFC。
/// </summary>
/// <param name="isOn"></param>
/// <param name="_mfcName"></param>
private void CloseMFC(bool isOn, string _mfcName)
{
lock (_mfcLock)
{
// 获取前置MFC
_mappedMfc = DEVICE.GetDevice<IoMFC>($"{Module}.{_mfcName}");
if (_mappedMfc == null)
{
// 如果未获取到前置MFC则直接操作蝶阀
EV.PostWarningLog(Module, $"Unable to find mapped MFC {_mfcName} of valve {Name}");
EV.PostInfoLog(Module, $"Turn {Display} {ValveStateToString(isOn)}");
SetPoint = isOn;
_operation = isOn;
}
else
{
EV.PostInfoLog(Module, $"Start to ramp {_mfcName} to 0.0{_mappedMfc.Unit}");
_isValveOnAfterMfcRamp = isOn;
_mappedMfc.Ramp(0, MFC_RAMP_DURATION_SEC);
_timMfcRampTimeout.Start(MFC_RAMP_TIMEOUT_SEC * 1000);
}
_timer.Start(2000);
}
}
private string ValveStateToString(bool isOn)
{
return isOn ? "On" : "Off";
}
public void Reset()
{
eventTrigger.RST = true;
forceOpenTrigger.RST = true;
lock (_mfcLock)
{
if (_mappedMfc != null)
{
_mappedMfc.Reset();
_mappedMfc = null;
_timMfcRampTimeout.Stop();
}
}
}
}
public static class ValveToMFCMap
{
/// <summary>
/// Key= IoValve_id , Value=IoMFC_id
/// </summary>
public static Dictionary<string, string> ValveControlMFC = new Dictionary<string, string>()
{
//{ "TMVent","Mfc60" },
{ "V96",$"Mfc38" },
{ "V94",$"Mfc36" },
};
}
}