Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../Devices/IoThrottleValve2.cs

794 lines
25 KiB
C#

using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Xml;
namespace Aitex.Core.RT.Device.Devices
{
public class IoThrottleValve2 : BaseDevice, IDevice
{
public PressureCtrlMode PressureMode
{
get
{
if (_aoPressureMode != null)
{
foreach (var ioMode in _ctrlModeIoValue)
{
if (_isFloatAioType)
{
if ((int)_aoPressureMode.FloatValue == ioMode.Value)
{
return ioMode.Key;
}
}
else
{
if (_aoPressureMode.Value == ioMode.Value)
{
return ioMode.Key;
}
}
}
return PressureCtrlMode.Undefined;
}
return PressureCtrlMode.Undefined;
}
set
{
if (_isFloatAioType)
_aoPressureMode.FloatValue = _ctrlModeIoValue[value];
else
{
_aoPressureMode.Value = (short)_ctrlModeIoValue[value];
}
}
}
public PressureCtrlMode ControlModeFeedback
{
get
{
if (_aiPressureMode != null)
{
foreach (var ioMode in _ctrlModeIoValue)
{
if (_isFloatAioType)
{
if ((int)_aiPressureMode.FloatValue == ioMode.Value)
{
return ioMode.Key;
}
}
else
{
if (_aiPressureMode.Value == ioMode.Value)
{
return ioMode.Key;
}
}
}
return PressureCtrlMode.Undefined;
}
return PressureCtrlMode.Undefined;
}
}
public bool TVValveEnable
{
get
{
if (_doTVValveEnable!=null)
{
return _doTVValveEnable.Value;
}
return false;
}
}
public float PositionSetpoint
{
get
{
return _aoPositionSetPoint == null ? 0 : (_isFloatAioType? _aoPositionSetPoint.FloatValue: _aoPositionSetPoint.Value);
}
set
{
if (_isFloatAioType)
{
_aoPositionSetPoint.FloatValue = value;
}
else
{
_aoPositionSetPoint.Value = (short)value;
}
}
}
public float PositionFeedback
{
get
{
return _aiPositionFeedback == null ? 0 : (_isFloatAioType ? _aiPositionFeedback.FloatValue: _aiPositionFeedback.Value);
}
}
public float PressureSetpoint
{
get
{
return _aoPressureSetPoint == null ? 0 : (_isFloatAioType ? _aoPressureSetPoint.FloatValue:_aoPressureSetPoint.Value);
}
set
{
if (_isFloatAioType)
{
_aoPressureSetPoint.FloatValue = value;
}
else
{
_aoPressureSetPoint.Value = (short)value;
}
}
}
public float PressureFeedback
{
get
{
return _aiPressureFeedback == null ? 0 : (_isFloatAioType ? _aiPressureFeedback.FloatValue:_aiPressureFeedback.Value);
}
}
private float _pressureSetPointByUse;
public float PressureSetpointByUse
{
get
{
return _pressureSetPointByUse;
}
set
{
_pressureSetPointByUse = value;
}
}
private float _positionSetPointByUse;
public float PositionSetpointByUse
{
get
{
return _positionSetPointByUse;
}
set
{
_positionSetPointByUse = value;
}
}
public float PositionDefaultValue
{
get
{
if (_positionDefaultValue != null)
{
return (float)_positionDefaultValue.DoubleValue;
}
else
{
return 0;
}
}
}
public float PressureDefaultValue
{
get
{
if (_pressureDefaultValue != null)
{
return (float)_pressureDefaultValue.DoubleValue;
}
else
{
return 1100;
}
}
//set
//{
// _pressureDefaultValue2 = value;
//}
}
public float ThrottlePositionModeMaxPressure
{
get
{
if (_throttlePositionModeMaxPressure != null)
{
return (float)_throttlePositionModeMaxPressure.DoubleValue;
}
else
{
return 400;
}
}
}
private SCConfigItem _positionDefaultValue;
private SCConfigItem _pressureDefaultValue;
private SCConfigItem _throttlePositionModeMaxPressure;
private DeviceTimer _closeTimer = new DeviceTimer();
private DeviceTimer _rampTimer = new DeviceTimer();
private double _rampTarget;
private double _rampInitValue;
private int _rampTime;
private DeviceTimer _rampTimer1 = new DeviceTimer();
private double _rampTarget1;
private double _rampInitValue1;
private int _rampTime1;
private AITThrottleValveData DeviceData
{
get
{
AITThrottleValveData data = new AITThrottleValveData()
{
Module = Module,
DeviceName = Name,
DeviceSchematicId = DeviceID,
DisplayName = Display,
Mode = (int)ControlModeFeedback,
PositionFeedback = PositionFeedback,
PositionSetPoint = PositionSetpointByUse,
PositionSetPointCurrent = PositionSetpoint,
PressureFeedback = PressureFeedback,
PressureSetPoint = PressureSetpointByUse,
PressureSetPointCurrent = PressureSetpoint,
TVEnable = TVValveEnable,
MaxValuePosition = 100,
MaxValuePressure = _unitPressure == "mbar" ? 1500 : 1500,
UnitPressure = _unitPressure,
};
return data;
}
}
private AIAccessor _aiPressureMode = null;
private AOAccessor _aoPressureMode = null;
private AIAccessor _aiPositionFeedback = null;
private AOAccessor _aoPositionSetPoint = null;
private AIAccessor _aiPressureFeedback = null;
private AOAccessor _aoPressureSetPoint = null;
private DOAccessor _doTVValveEnable = null;
private string _unitPressure;
private Dictionary<PressureCtrlMode, int> _ctrlModeIoValue = new Dictionary<PressureCtrlMode, int>();
private bool _isFloatAioType = false;
private R_TRIG _setTvCloseTrig = new R_TRIG();
public IoThrottleValve2(string module, XmlElement node, string ioModule = "")
{
var attrModule = node.GetAttribute("module");
base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
string scBasePath = node.GetAttribute("scBasePath");
if (string.IsNullOrEmpty(scBasePath))
scBasePath = $"{Module}.{Name}";
else
{
scBasePath = scBasePath.Replace("{module}", Module);
}
_unitPressure = node.GetAttribute("unit");
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
_aiPressureMode = ParseAiNode("aiStatus", node, ioModule);
_aoPressureMode = ParseAoNode("aoPressureMode", node, ioModule);
_aiPositionFeedback = ParseAiNode("aiPositionFeedback", node, ioModule);
_aoPositionSetPoint = ParseAoNode("aoPositionSetPoint", node, ioModule);
_aiPressureFeedback = ParseAiNode("aiPressureFeedback", node, ioModule);
_aoPressureSetPoint = ParseAoNode("aoPressureSetPoint", node, ioModule);
_doTVValveEnable = ParseDoNode("doTVValveEnable", node, ioModule);
_positionDefaultValue = ParseScNode("positionDefaultValue", node, ioModule, $"{scBasePath}.ThrottlePositionDefaultValue");
_pressureDefaultValue = ParseScNode("pressureDefaultValue", node, ioModule, $"{scBasePath}.ThrottlePressureDefaultValue");
_throttlePositionModeMaxPressure = ParseScNode("throttlePositionModeMaxPressure", node, ioModule, $"{scBasePath}.ThrottlePositionModeMaxPressure");
EnumLoop<PressureCtrlMode>.ForEach(x => _ctrlModeIoValue[x] = -1);
if (!string.IsNullOrEmpty(node.GetAttribute("modeValuePressure")))
{
_ctrlModeIoValue[PressureCtrlMode.TVPressureCtrl] = int.Parse(node.GetAttribute("modeValuePressure"));
}
if (!string.IsNullOrEmpty(node.GetAttribute("modeValuePosition")))
{
_ctrlModeIoValue[PressureCtrlMode.TVPositionCtrl] = int.Parse(node.GetAttribute("modeValuePosition"));
}
if (!string.IsNullOrEmpty(node.GetAttribute("modeValueOpen")))
{
_ctrlModeIoValue[PressureCtrlMode.TVOpen] = int.Parse(node.GetAttribute("modeValueOpen"));
}
if (!string.IsNullOrEmpty(node.GetAttribute("modeValueClose")))
{
_ctrlModeIoValue[PressureCtrlMode.TVClose] = int.Parse(node.GetAttribute("modeValueClose"));
}
//PressureDefaultValue = (float)_pressureDefaultValue.DoubleValue;
}
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
DATA.Subscribe($"{Module}.{Name}.PositionSetPoint", () => PositionSetpoint);
DATA.Subscribe($"{Module}.{Name}.PositionFeedback", () => PositionFeedback);
DATA.Subscribe($"{Module}.{Name}.PressureSetPoint", () => PressureSetpoint);
DATA.Subscribe($"{Module}.{Name}.PressureFeedback", () => PressureFeedback);
DATA.Subscribe($"{Module}.{Name}.Mode", () => ControlModeFeedback);
DATA.Subscribe($"{Module}.{Name}.TVValveEnable", () => TVValveEnable);
OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetMode}", SetMode);
OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPosition}", SetPosition);
OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPressure}", SetPressure);
OP.Subscribe($"{Module}.{Name}.SetPositionToZero", SetPositionToZero);
OP.Subscribe($"{Module}.{Name}.SetTVEnableRoutine", SetTVEnableRoutine);
OP.Subscribe($"{Module}.{Name}.SetTVValveEnable", (function, args) =>
{
bool bOn = Convert.ToBoolean((string)args[0]);
SetTVEnable(bOn, out string reason);
return true;
});
return true;
}
public bool SetMode(PressureCtrlMode mode, out string reason)
{
reason = String.Empty;
if (mode == ControlModeFeedback)
{
return true;
}
if (mode == PressureCtrlMode.TVClose)
{
_rampTimer.Stop();
_rampTimer1.Stop();
reason = $"{Display} set to {mode}";
PressureMode = mode;
}
else
{
_rampTimer.Stop();
_rampTimer1.Stop();
if (!_rampTimer.IsIdle() || !_rampTimer1.IsIdle())
{
//在压力正在调节过程中不允许切换模式
reason = "Can not set mode while pressure is ramping!";
return false;
}
if (mode == PressureCtrlMode.TVPositionCtrl)
{
if(PressureFeedback > ThrottlePositionModeMaxPressure)
{
reason = $"Change Positon Mode Failed,Current Pressure is {PressureFeedback},More than change Positon Mode Max Pressure {ThrottlePositionModeMaxPressure}!";
EV.PostWarningLog(Module, reason);
return false;
}
}
reason = $"{Display} set to {mode}";
bool flag = PressureMode != mode;
PressureMode = mode;
if(flag)
{
if(PressureMode == PressureCtrlMode.TVPressureCtrl)
{
PressureSetpoint = PressureDefaultValue;
}
else if (PressureMode == PressureCtrlMode.TVPositionCtrl)
{
PositionSetpoint = PositionDefaultValue;
}
}
}
EV.PostInfoLog(Module, reason);
return true;
}
private bool SetMode(out string reason, int time, object[] param)
{
return SetMode((PressureCtrlMode)Enum.Parse(typeof(PressureCtrlMode), (string)param[0], true),
out reason);
}
//private bool SetPosition(float position, out string reason)
//{
// PositionSetpoint = position;
// reason = $"{Display} position set to {position}";
// EV.PostInfoLog(Module, reason);
// return true;
//}
public bool SetPosition(out string reason, int time, object[] param)
{
reason = String.Empty;
if (ControlModeFeedback != PressureCtrlMode.TVPositionCtrl)
{
reason = "TV is not in position control mode";
return false;
}
PositionSetpointByUse = (float)Convert.ToDouble(param[0]);
//if (time > 0)
//{
// _rampTimer1.Stop();
// Ramp(Convert.ToDouble(param[0]), time);
//}
//else
//{
// _rampTimer1.Stop();
// double rate = SC.GetValue<double>($"PM.{Module}.ThrottlePositionRate");
// RampByRatePosition(Convert.ToDouble(param[0]), rate);
//}
_rampTimer1.Stop();
double rate = SC.GetValue<double>($"PM.{Module}.ThrottlePositionRate");
RampByRatePosition(Convert.ToDouble(param[0]), rate);
return true;
}
public bool SetPressure(out string reason, int time, object[] param)
{
reason = String.Empty;
if (ControlModeFeedback != PressureCtrlMode.TVPressureCtrl)
{
reason = "TV is not in pressure control mode";
return false;
}
PressureSetpointByUse = (float)Convert.ToDouble(param[0]);
_rampTimer.Stop();
if (time > 0)
{
Ramp(Convert.ToDouble(param[0]), time);
}
else
{
double rate = SC.GetValue<double>($"PM.{Module}.ThrottlePressureRate");
RampByRate(Convert.ToDouble(param[0]), rate);
}
return true;
}
//public bool SetPressureToDefault(string reason, object[] param)
//{
// _rampTimer.Stop();
// if (PressureMode != PressureCtrlMode.TVPositionCtrl)
// {
// PressureMode = PressureCtrlMode.TVPositionCtrl;
// }
// PositionSetpoint = PositionDefaultValue;
// PressureSetpoint = PressureDefaultValue;
// PositionSetpointByUse = PositionDefaultValue;
// PressureSetpointByUse = PressureDefaultValue;
// return true;
//}
public bool SetPositionToZero(string reason, object[] param)
{
_rampTimer.Stop();
_rampTimer1.Stop();
if (ControlModeFeedback != PressureCtrlMode.TVPositionCtrl)
{
PressureMode = PressureCtrlMode.TVPositionCtrl;
}
PositionSetpoint = 0;
//PressureSetpoint = PressureDefaultValue;
PositionSetpointByUse = 0;
//PressureSetpointByUse = PressureDefaultValue;
return true;
}
//public bool SetPositionImmediately(string reason, object[] param)
//{
// _rampTimer.Stop();
// reason = String.Empty;
// PositionSetpoint = 0;
// return true;
//}
//private bool SetPressure(float pressure, out string reason)
//{
// PressureSetpoint = pressure;
// reason = $"{Display} pressure set to {pressure} {_unitPressure}";
// EV.PostInfoLog(Module, reason);
// return true;
//}
public bool SetTVEnable(bool isEnable, out string reason)
{
reason = String.Empty;
_rampTimer.Stop();
_rampTimer1.Stop();
//开阀时设置Ai的默认值
if (isEnable)
{
if (!_doTVValveEnable.SetValue(isEnable, out reason))
return false;
Thread.Sleep(50);
if (ControlModeFeedback != PressureCtrlMode.TVPressureCtrl)
{
PressureMode = PressureCtrlMode.TVPressureCtrl;
}
Thread.Sleep(50);
//PositionSetpoint = PositionDefaultValue;
PressureSetpoint = PressureDefaultValue;
//PositionSetpointByUse = PositionDefaultValue;
PressureSetpointByUse = PressureDefaultValue;
}
else
{
if (ControlModeFeedback == PressureCtrlMode.TVPressureCtrl)
{
PressureSetpoint = PressureDefaultValue;
PressureSetpointByUse = PressureDefaultValue;
}
else
{
PositionSetpoint = PositionDefaultValue;
PositionSetpointByUse = PositionDefaultValue;
}
Thread.Sleep(50);
if (ControlModeFeedback != PressureCtrlMode.TVClose)//强关模式
{
PressureMode = PressureCtrlMode.TVClose;
}
if (!_doTVValveEnable.SetValue(isEnable, out reason))
return false;
}
reason = $"{Display} set to {isEnable}";
EV.PostInfoLog(Module, reason);
return true;
}
public bool SetTVEnableState(bool isEnable, out string reason)
{
_rampTimer.Stop();
_rampTimer1.Stop();
if (!_doTVValveEnable.SetValue(isEnable, out reason))
return false;
reason = $"{Display} set to {isEnable}";
EV.PostInfoLog(Module, reason);
return true;
}
public bool SetTVEnableRoutine(out string reason,int time,object[] param)
{
_rampTimer.Stop();
_rampTimer1.Stop();
bool isEnable = Convert.ToBoolean(param[0]);
if (!_doTVValveEnable.SetValue(isEnable, out reason))
return false;
reason = $"{Display} set to {isEnable}";
EV.PostInfoLog(Module, reason);
return true;
}
public void Terminate()
{
}
public void StopRamp()
{
Ramp(PressureSetpoint, 0);
}
public void Monitor()
{
try
{
MonitorRamping();
MonitorRampingPosition();
//MonitorClose();
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
private void MonitorClose()
{
//InterLock
if (!_doTVValveEnable.Value && ControlModeFeedback != PressureCtrlMode.TVClose)
{
PressureMode = PressureCtrlMode.TVClose;
}
}
public void RampByRate(double target, double rate)
{
if (ControlModeFeedback == PressureCtrlMode.TVPressureCtrl)
{
_rampInitValue = PressureFeedback;// PressureSetpoint; //ramp 初始值取实际读取值
_rampTime = 0;
if (rate > 0)
{
_rampTime = Math.Abs((int)((target - PressureFeedback) / rate) * 1000); //根据速率计算超时时间
}
_rampTarget = target;
_rampTimer.Start(_rampTime);
}
}
private void RampByRatePosition(double target, double rate)
{
if (ControlModeFeedback == PressureCtrlMode.TVPositionCtrl)
{
_rampInitValue1 = PositionFeedback;//PositionSetpoint;
_rampTime1 = 0;
if (rate > 0)
{
_rampTime1 = Math.Abs((int)((target - PositionFeedback) / rate) * 1000);
}
_rampTarget1 = target;
_rampTimer1.Start(_rampTime1);
}
}
private void Ramp(double target, int time)
{
if (ControlModeFeedback == PressureCtrlMode.TVPositionCtrl)
{
_rampInitValue1 = PositionFeedback; //PositionSetpoint; //ramp 初始值取实际读取值
_rampTime1 = time;
_rampTarget1 = target;
_rampTimer1.Start(_rampTime1);
}
else
{
_rampInitValue = PressureFeedback;// PressureSetpoint; //ramp 初始值取当前设定值,而非实际读取值.零漂问题
_rampTime = time;
_rampTarget = target;
_rampTimer.Start(_rampTime);
}
}
private void MonitorRamping()
{
if (!_rampTimer.IsIdle())
{
if (ControlModeFeedback == PressureCtrlMode.TVPressureCtrl)
{
//压力模式
if (_rampTimer.IsTimeout() || _rampTime == 0)
{
_rampTimer.Stop();
PressureSetpoint = (float)_rampTarget;
}
else
{
PressureSetpoint = (float)(_rampInitValue + (_rampTarget - _rampInitValue) * _rampTimer.GetElapseTime() / _rampTime);
}
}
}
}
private void MonitorRampingPosition()
{
if (!_rampTimer1.IsIdle())
{
if (ControlModeFeedback == PressureCtrlMode.TVPositionCtrl)
{
if (_rampTimer1.IsTimeout() || _rampTime1 == 0)
{
_rampTimer1.Stop();
PositionSetpoint = (float)_rampTarget1;
}
else
{
PositionSetpoint = (float)(_rampInitValue1 + (_rampTarget1 - _rampInitValue1) * _rampTimer1.GetElapseTime() / _rampTime1);
}
}
}
}
public void Reset()
{
_setTvCloseTrig.RST = true;
}
}
}