using Aitex.Common.Util; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.ParameterCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Systems; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Event; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; namespace FurnaceRT.Devices { public class IoAPC : BaseDevice, IDevice { #region Filed private DIAccessor _diP1ZeroOffsetOutRangeAlm; private DIAccessor _diP1ZeroAdjOutRangeAlm; private DIAccessor _diP1SpanAdjOutRangeAlm; private DIAccessor _diP2ZeroOffsetOutRangeAlm; private DIAccessor _diP2ZeroAdjOutRangeAlm; private DIAccessor _diP2SpanAdjOutRangeAlm; private DIAccessor _diP1PressCtrlInterlockAlm; private DIAccessor _diP2PressCtrlInterlockAlm; private DIAccessor _diValveOpenCtrlInterlockAlm; private DIAccessor _diValveHoldCtrlInterlockAlm; private DIAccessor _diValveCloseInterlockAlm; private DIAccessor _diAutoTeachingInterlockAlm; private DIAccessor _diP1DisconnectionAlm; private DIAccessor _diP2DisconnectionAlm; private DIAccessor _diPumpStopInterlockAlm; private DIAccessor _diAutoTeachingErr1Alm; private DIAccessor _diAutoTeachingErr2Alm; private DOAccessor _doVGUnit; private DOAccessor _doAoDataReadSysConfig; private DOAccessor _doAoDataWriteSysConfig; private DOAccessor _doAoDataReadCusConfig; private DOAccessor _doAoDataWriteCusConfig; private AIAccessor _aiValueSensorInput1; private AIAccessor _aiValueSensorInput2; private AIAccessor _aiSelectController; private AIAccessor _aiPositionActualValue; private AIAccessor _aiControlModeStatus; private AIAccessor _aiHomeStatus; private AIAccessor _aiWarningStatus1; private AIAccessor _aiWarningStatus2; private AIAccessor _aiWarningStatus3; private AIAccessor _aiWarningStatus4; private AIAccessor _aiWarningStatus5; private AIAccessor _aiWarningStatus6; private AIAccessor _aiErrorStatus1; private AIAccessor _aiErrorStatus2; private AIAccessor _aiErrorStatus3; private AIAccessor _aiErrorStatus4; private AIAccessor _aiValveStatusThreshold; private AIAccessor _aiForbidInterlockOutbreak; private AIAccessor _aiSlowVacuumModeSetting; private AIAccessor _aiInterlock1; private AIAccessor _aiInterlock2; private AIAccessor _aiInterlock3; private AIAccessor _aiInterlockConstantOfInterlock3; private AIAccessor _aiP1SensorOffsetSetting; private AIAccessor _aiPosMonOffsetSetting; private AOAccessor _aoZeroResetP1; private AOAccessor _aoZeroAdjustP1; private AOAccessor _aoSpanAdjustP1; private AOAccessor _aoZeroResetP2; private AOAccessor _aoZeroAdjustP2; private AOAccessor _aoSpanAdjustP2; private AOAccessor _aoSlowVacuumTargetPressure; private AOAccessor _aoValveStatusThreshold; private AOAccessor _aoForbidInterlockOutbreak; private AOAccessor _aoSlowVacuumModeSetting; private AOAccessor _aoInterlock1; private AOAccessor _aoInterlock2; private AOAccessor _aoInterlock3; private AOAccessor _aoInterlockConstantOfInterlock3; private AOAccessor _aoP1SensorOffsetSetting; private AOAccessor _aoPosMonOffsetSetting; private AOAccessor _aoSensorAdjustReset; private AOAccessor _aoSlowVacuumRate; private AOAccessor _aoSlowVacuumP; private AOAccessor _aoSlowVacuumI; private AOAccessor _aoSlowVacuumD; private AOAccessor _aoSlowVacuumA; private AOAccessor _aoControllerModeSelect; private AOAccessor _aoSpecifyTargetVacuumPressureControl; private AOAccessor _aoSpecifyTargetOpeningForValveOpeningControl; private AOAccessor _aoSpecifyControlMode; private AOAccessor _aoRangeUpperLimitSensorInput; private AOAccessor _aoController1; private AOAccessor _aoController1P; private AOAccessor _aoController1I; private AOAccessor _aoController1D; private AOAccessor _aoController1A; private AOAccessor _aoController1CH; private AOAccessor _aoController1CL; private AOAccessor _aoController1Offset; private AOAccessor _aoController2; private AOAccessor _aoController2P; private AOAccessor _aoController2I; private AOAccessor _aoController2D; private AOAccessor _aoController2A; private AOAccessor _aoController2CH; private AOAccessor _aoController2CL; private AOAccessor _aoController2Offset; private AOAccessor _aoController3; private AOAccessor _aoController3P; private AOAccessor _aoController3I; private AOAccessor _aoController3D; private AOAccessor _aoController3A; private AOAccessor _aoController3CH; private AOAccessor _aoController3CL; private AOAccessor _aoController3Offset; private AOAccessor _aoController4; private AOAccessor _aoController4P; private AOAccessor _aoController4I; private AOAccessor _aoController4D; private AOAccessor _aoController4A; private AOAccessor _aoController4CH; private AOAccessor _aoController4CL; private AOAccessor _aoController4Offset; private AOAccessor _aoController5; private AOAccessor _aoController5P; private AOAccessor _aoController5I; private AOAccessor _aoController5D; private AOAccessor _aoController5A; private AOAccessor _aoController5CH; private AOAccessor _aoController5CL; private AOAccessor _aoController5Offset; private AOAccessor _aoController6; private AOAccessor _aoController6P; private AOAccessor _aoController6I; private AOAccessor _aoController6D; private AOAccessor _aoController6A; private AOAccessor _aoController6CH; private AOAccessor _aoController6CL; private AOAccessor _aoController6Offset; private AOAccessor _aoController7; private AOAccessor _aoController7P; private AOAccessor _aoController7I; private AOAccessor _aoController7D; private AOAccessor _aoController7A; private AOAccessor _aoController7CH; private AOAccessor _aoController7CL; private AOAccessor _aoController7Offset; private AOAccessor _aoController8; private AOAccessor _aoController8P; private AOAccessor _aoController8I; private AOAccessor _aoController8D; private AOAccessor _aoController8A; private AOAccessor _aoController8CH; private AOAccessor _aoController8CL; private AOAccessor _aoController8Offset; private AOAccessor _aoController9; private AOAccessor _aoController9P; private AOAccessor _aoController9I; private AOAccessor _aoController9D; private AOAccessor _aoController9A; private AOAccessor _aoController9CH; private AOAccessor _aoController9CL; private AOAccessor _aoController9Offset; private AOAccessor _aoController10; private AOAccessor _aoController10P; private AOAccessor _aoController10I; private AOAccessor _aoController10D; private AOAccessor _aoController10A; private AOAccessor _aoController10CH; private AOAccessor _aoController10CL; private AOAccessor _aoController10Offset; private bool _isFloatAioType = false; private AITAPCData _deviceData; private bool _isWait; private float _waitHigh; private float _waitLow; private Stopwatch _unloadTimer = new Stopwatch(); private IoValve _valveAV71; private R_TRIG _av71OpenTrig = new R_TRIG(); private Stopwatch _apcSetModeTimer = new Stopwatch(); private int _apcSetModeTimeOutSec = 5; private bool _isInit = false; private Stopwatch _initTimer = new Stopwatch(); private Stopwatch _readConfigTimer = new Stopwatch(); #endregion #region Property public int SelectedControllerFeedback => (int)(_aiSelectController.FloatValue + 0.0001); public int ModeFeedback => (int)(_aiControlModeStatus.FloatValue + 0.0001); public int ModeSetPoint => (int)(_aoSpecifyControlMode.FloatValue + 0.0001); public int HomingStatus => (int)(_aiHomeStatus.FloatValue + 0.0001); public bool IsError { get; set; } public bool IsNeedWaitComplete { get; set; } public string PressureUnit { get; set; } private float _basePressure = 0; private float _valveStausThreshold; public float ValveStatusThreshold { get { if(_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiValveStatusThreshold.FloatValue; } return _valveStausThreshold; } set { _valveStausThreshold = value; SC.SetItemValue($"{Module}.{Name}.ValveStatusThreshold", value); } } private float _slowVacuumModeSetting; public float SlowVacuumModeSetting { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiSlowVacuumModeSetting.FloatValue; } return _slowVacuumModeSetting; } set { _slowVacuumModeSetting = value; SC.SetItemValue($"{Module}.{Name}.SlowVacuumModeSetting", value); } } private float interlock1; public float Interlock1 { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiInterlock1.FloatValue; } return interlock1; } set { interlock1 = value; SC.SetItemValue($"{Module}.{Name}.Interlock1", value); } } private float interlock2; public float Interlock2 { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiInterlock2.FloatValue; } return interlock2; } set { interlock2 = value; SC.SetItemValue($"{Module}.{Name}.Interlock2", value); } } private float interlock3; public float Interlock3 { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiInterlock3.FloatValue; } return interlock3; } set { interlock3 = value; SC.SetItemValue($"{Module}.{Name}.Interlock3", value); } } private float _interlockConstantOfInterlock3; public float InterlockConstantOfInterlock3 { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiInterlockConstantOfInterlock3.FloatValue; } return _interlockConstantOfInterlock3; } set { _interlockConstantOfInterlock3 = value; SC.SetItemValue($"{Module}.{Name}.InterlockConstantOfInterlock3", value); } } private float _p1SensorOffsetSetting; public float P1SensorOffsetSetting { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiP1SensorOffsetSetting.FloatValue; } return _p1SensorOffsetSetting; } set { _p1SensorOffsetSetting = value; SC.SetItemValue($"{Module}.{Name}.P1SensorOffsetSetting", value); } } private float _posMonOffsetSetting; public float PosMonOffsetSetting { get { if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000) { return _aiPosMonOffsetSetting.FloatValue; } return _posMonOffsetSetting; } set { _posMonOffsetSetting = value; SC.SetItemValue($"{Module}.{Name}.PosMonOffsetSetting", value); } } public AlarmEventItem APCSetModeAlarm { get; set; } public AlarmEventItem APCPressure1ToleranceWarning { get; set; } public AlarmEventItem APCPressure1ToleranceAlarm { get; set; } public AlarmEventItem APCPressure2ToleranceWarning { get; set; } public AlarmEventItem APCPressure2ToleranceAlarm { get; set; } public AlarmEventItem APCAngleToleranceWarning { get; set; } public AlarmEventItem APCAngleToleranceAlarm { get; set; } public AITAPCData DeviceData => _deviceData; #endregion public IoAPC(string module, XmlElement node, string ioModule = "") { base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"); base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); _isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float"); _diP1ZeroOffsetOutRangeAlm = ParseDiNode("diP1ZeroOffsetOutRangeAlm", node, ioModule); _diP1ZeroAdjOutRangeAlm = ParseDiNode("diP1ZeroAdjOutRangeAlm", node, ioModule); _diP1SpanAdjOutRangeAlm = ParseDiNode("diP1SpanAdjOutRangeAlm", node, ioModule); _diP2ZeroOffsetOutRangeAlm = ParseDiNode("diP2ZeroOffsetOutRangeAlm", node, ioModule); _diP2ZeroAdjOutRangeAlm = ParseDiNode("diP2ZeroAdjOutRangeAlm", node, ioModule); _diP2SpanAdjOutRangeAlm = ParseDiNode("diP2SpanAdjOutRangeAlm", node, ioModule); _diP1PressCtrlInterlockAlm = ParseDiNode("diP1PressCtrlInterlockAlm", node, ioModule); _diP2PressCtrlInterlockAlm = ParseDiNode("diP2PressCtrlInterlockAlm", node, ioModule); _diValveOpenCtrlInterlockAlm = ParseDiNode("diValveOpenCtrlInterlockAlm", node, ioModule); _diValveHoldCtrlInterlockAlm = ParseDiNode("diValveHoldCtrlInterlockAlm", node, ioModule); _diValveCloseInterlockAlm = ParseDiNode("diValveCloseInterlockAlm", node, ioModule); _diAutoTeachingInterlockAlm = ParseDiNode("diAutoTeachingInterlockAlm", node, ioModule); _diP1DisconnectionAlm = ParseDiNode("diP1DisconnectionAlm", node, ioModule); _diP2DisconnectionAlm = ParseDiNode("diP2DisconnectionAlm", node, ioModule); _diPumpStopInterlockAlm = ParseDiNode("diPumpStopInterlockAlm", node, ioModule); _diAutoTeachingErr1Alm = ParseDiNode("diAutoTeachingErr1Alm", node, ioModule); _diAutoTeachingErr2Alm = ParseDiNode("diAutoTeachingErr2Alm", node, ioModule); _doVGUnit = ParseDoNode("doVGUnit", node, ioModule); _doAoDataWriteSysConfig = ParseDoNode("doAoDataWriteSysConfig", node, ioModule); _doAoDataReadSysConfig = ParseDoNode("doAoDataReadSysConfig", node, ioModule); _doAoDataReadCusConfig = ParseDoNode("doAoDataReadCusConfig", node, ioModule); _doAoDataWriteCusConfig = ParseDoNode("doAoDataWriteCusConfig", node, ioModule); _aiValueSensorInput1 = ParseAiNode("aiValueSensorInput1", node, ioModule); _aiValueSensorInput2 = ParseAiNode("aiValueSensorInput2", node, ioModule); _aiSelectController = ParseAiNode("aiSelectController", node, ioModule); _aiPositionActualValue = ParseAiNode("aiPositionActualValue", node, ioModule); _aiControlModeStatus = ParseAiNode("aiControlModeStatus", node, ioModule); _aiHomeStatus = ParseAiNode("aiHomeStatus", node, ioModule); _aiWarningStatus1 = ParseAiNode("aiWarningStatus1", node, ioModule); _aiWarningStatus2 = ParseAiNode("aiWarningStatus2", node, ioModule); _aiWarningStatus3 = ParseAiNode("aiWarningStatus3", node, ioModule); _aiWarningStatus4 = ParseAiNode("aiWarningStatus4", node, ioModule); _aiWarningStatus5 = ParseAiNode("aiWarningStatus5", node, ioModule); _aiWarningStatus6 = ParseAiNode("aiWarningStatus6", node, ioModule); _aiErrorStatus1 = ParseAiNode("aiErrorStatus1", node, ioModule); _aiErrorStatus2 = ParseAiNode("aiErrorStatus2", node, ioModule); _aiErrorStatus3 = ParseAiNode("aiErrorStatus3", node, ioModule); _aiErrorStatus4 = ParseAiNode("aiErrorStatus4", node, ioModule); _aiValveStatusThreshold = ParseAiNode("aiValveStatusThreshold", node, ioModule); _aiForbidInterlockOutbreak = ParseAiNode("aiForbidInterlockOutbreak", node, ioModule); _aiSlowVacuumModeSetting = ParseAiNode("aiSlowVacuumModeSetting", node, ioModule); _aiInterlock1 = ParseAiNode("aiInterlock1", node, ioModule); _aiInterlock2 = ParseAiNode("aiInterlock2", node, ioModule); _aiInterlock3 = ParseAiNode("aiInterlock3", node, ioModule); _aiInterlockConstantOfInterlock3 = ParseAiNode("aiInterlockConstantOfInterlock3", node, ioModule); _aiP1SensorOffsetSetting = ParseAiNode("aiP1SensorOffsetSetting", node, ioModule); _aiPosMonOffsetSetting = ParseAiNode("aiPosMonOffsetSetting", node, ioModule); _aoZeroResetP1 = ParseAoNode("aoZeroResetP1", node, ioModule); _aoZeroAdjustP1 = ParseAoNode("aoZeroAdjustP1", node, ioModule); _aoSpanAdjustP1 = ParseAoNode("aoSpanAdjustP1", node, ioModule); _aoZeroResetP2 = ParseAoNode("aoZeroResetP2", node, ioModule); _aoZeroAdjustP2 = ParseAoNode("aoZeroAdjustP2", node, ioModule); _aoSpanAdjustP2 = ParseAoNode("aoSpanAdjustP2", node, ioModule); _aoSlowVacuumTargetPressure = ParseAoNode("aoSlowVacuumTargetPressure", node, ioModule); _aoValveStatusThreshold = ParseAoNode("aoValveStatusThreshold", node, ioModule); _aoForbidInterlockOutbreak = ParseAoNode("aoForbidInterlockOutbreak", node, ioModule); _aoSlowVacuumModeSetting = ParseAoNode("aoSlowVacuumModeSetting", node, ioModule); _aoInterlock1 = ParseAoNode("aoInterlock1", node, ioModule); _aoInterlock2 = ParseAoNode("aoInterlock2", node, ioModule); _aoInterlock3 = ParseAoNode("aoInterlock3", node, ioModule); _aoInterlockConstantOfInterlock3 = ParseAoNode("aoInterlockConstantOfInterlock3", node, ioModule); _aoP1SensorOffsetSetting = ParseAoNode("aoP1SensorOffsetSetting", node, ioModule); _aoPosMonOffsetSetting = ParseAoNode("aoPosMonOffsetSetting", node, ioModule); _aoSensorAdjustReset = ParseAoNode("aoSensorAdjustReset", node, ioModule); _aoSlowVacuumRate = ParseAoNode("aoSlowVacuumRate", node, ioModule); _aoSlowVacuumP = ParseAoNode("aoSlowVacuumP", node, ioModule); _aoSlowVacuumI = ParseAoNode("aoSlowVacuumI", node, ioModule); _aoSlowVacuumD = ParseAoNode("aoSlowVacuumD", node, ioModule); _aoSlowVacuumA = ParseAoNode("aoSlowVacuumA", node, ioModule); _aoControllerModeSelect = ParseAoNode("aoControllerModeSelect", node, ioModule); _aoSpecifyTargetVacuumPressureControl = ParseAoNode("aoSpecifyTargetVacuumPressureControl", node, ioModule); _aoSpecifyTargetOpeningForValveOpeningControl = ParseAoNode("aoSpecifyTargetOpeningForValveOpeningControl", node, ioModule); _aoSpecifyControlMode = ParseAoNode("aoSpecifyControlMode", node, ioModule); _aoRangeUpperLimitSensorInput = ParseAoNode("aoRangeUpperLimitSensorInput", node, ioModule); _aoController1 = ParseAoNode("aoController1", node, ioModule); _aoController1P = ParseAoNode("aoController1P", node, ioModule); _aoController1I = ParseAoNode("aoController1I", node, ioModule); _aoController1D = ParseAoNode("aoController1D", node, ioModule); _aoController1A = ParseAoNode("aoController1A", node, ioModule); _aoController1CH = ParseAoNode("aoController1CH", node, ioModule); _aoController1CL = ParseAoNode("aoController1CL", node, ioModule); _aoController1Offset = ParseAoNode("aoController1Offset", node, ioModule); _aoController2 = ParseAoNode("aoController2", node, ioModule); _aoController2P = ParseAoNode("aoController2P", node, ioModule); _aoController2I = ParseAoNode("aoController2I", node, ioModule); _aoController2D = ParseAoNode("aoController2D", node, ioModule); _aoController2A = ParseAoNode("aoController2A", node, ioModule); _aoController2CH = ParseAoNode("aoController2CH", node, ioModule); _aoController2CL = ParseAoNode("aoController2CL", node, ioModule); _aoController2Offset = ParseAoNode("aoController2Offset", node, ioModule); _aoController3 = ParseAoNode("aoController3", node, ioModule); _aoController3P = ParseAoNode("aoController3P", node, ioModule); _aoController3I = ParseAoNode("aoController3I", node, ioModule); _aoController3D = ParseAoNode("aoController3D", node, ioModule); _aoController3A = ParseAoNode("aoController3A", node, ioModule); _aoController3CH = ParseAoNode("aoController3CH", node, ioModule); _aoController3CL = ParseAoNode("aoController3CL", node, ioModule); _aoController3Offset = ParseAoNode("aoController3Offset", node, ioModule); _aoController4 = ParseAoNode("aoController4", node, ioModule); _aoController4P = ParseAoNode("aoController4P", node, ioModule); _aoController4I = ParseAoNode("aoController4I", node, ioModule); _aoController4D = ParseAoNode("aoController4D", node, ioModule); _aoController4A = ParseAoNode("aoController4A", node, ioModule); _aoController4CH = ParseAoNode("aoController4CH", node, ioModule); _aoController4CL = ParseAoNode("aoController4CL", node, ioModule); _aoController4Offset = ParseAoNode("aoController4Offset", node, ioModule); _aoController5 = ParseAoNode("aoController5", node, ioModule); _aoController5P = ParseAoNode("aoController5P", node, ioModule); _aoController5I = ParseAoNode("aoController5I", node, ioModule); _aoController5D = ParseAoNode("aoController5D", node, ioModule); _aoController5A = ParseAoNode("aoController5A", node, ioModule); _aoController5CH = ParseAoNode("aoController5CH", node, ioModule); _aoController5CL = ParseAoNode("aoController5CL", node, ioModule); _aoController5Offset = ParseAoNode("aoController5Offset", node, ioModule); _aoController6 = ParseAoNode("aoController6", node, ioModule); _aoController6P = ParseAoNode("aoController6P", node, ioModule); _aoController6I = ParseAoNode("aoController6I", node, ioModule); _aoController6D = ParseAoNode("aoController6D", node, ioModule); _aoController6A = ParseAoNode("aoController6A", node, ioModule); _aoController6CH = ParseAoNode("aoController6CH", node, ioModule); _aoController6CL = ParseAoNode("aoController6CL", node, ioModule); _aoController6Offset = ParseAoNode("aoController6Offset", node, ioModule); _aoController7 = ParseAoNode("aoController7", node, ioModule); _aoController7P = ParseAoNode("aoController7P", node, ioModule); _aoController7I = ParseAoNode("aoController7I", node, ioModule); _aoController7D = ParseAoNode("aoController7D", node, ioModule); _aoController7A = ParseAoNode("aoController7A", node, ioModule); _aoController7CH = ParseAoNode("aoController7CH", node, ioModule); _aoController7CL = ParseAoNode("aoController7CL", node, ioModule); _aoController7Offset = ParseAoNode("aoController7Offset", node, ioModule); _aoController8 = ParseAoNode("aoController8", node, ioModule); _aoController8P = ParseAoNode("aoController8P", node, ioModule); _aoController8I = ParseAoNode("aoController8I", node, ioModule); _aoController8D = ParseAoNode("aoController8D", node, ioModule); _aoController8A = ParseAoNode("aoController8A", node, ioModule); _aoController8CH = ParseAoNode("aoController8CH", node, ioModule); _aoController8CL = ParseAoNode("aoController8CL", node, ioModule); _aoController8Offset = ParseAoNode("aoController8Offset", node, ioModule); _aoController9 = ParseAoNode("aoController9", node, ioModule); _aoController9P = ParseAoNode("aoController9P", node, ioModule); _aoController9I = ParseAoNode("aoController9I", node, ioModule); _aoController9D = ParseAoNode("aoController9D", node, ioModule); _aoController9A = ParseAoNode("aoController9A", node, ioModule); _aoController9CH = ParseAoNode("aoController9CH", node, ioModule); _aoController9CL = ParseAoNode("aoController9CL", node, ioModule); _aoController9Offset = ParseAoNode("aoController9Offset", node, ioModule); _aoController10 = ParseAoNode("aoController10", node, ioModule); _aoController10P = ParseAoNode("aoController10P", node, ioModule); _aoController10I = ParseAoNode("aoController10I", node, ioModule); _aoController10D = ParseAoNode("aoController10D", node, ioModule); _aoController10A = ParseAoNode("aoController10A", node, ioModule); _aoController10CH = ParseAoNode("aoController10CH", node, ioModule); _aoController10CL = ParseAoNode("aoController10CL", node, ioModule); _aoController10Offset = ParseAoNode("aoController10Offset", node, ioModule); PressureUnit = SC.GetStringValue($"{Module}.{Name}.PressureUnit"); } public bool Initialize() { if (System.Diagnostics.Debugger.IsAttached) { var oj = DEVICE.GetDevice($"{Module}.{Name}"); foreach (var pi in oj.GetType().GetProperties()) { if (pi.PropertyType.Name.EndsWith("Accessor")) { var value = pi.GetValue(oj); if (value == null) { LOG.Write($"{Module}.{Name} {pi.Name} is null"); } } } } _deviceData = new AITAPCData() { Module = Module, DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = Display, }; DATA.Subscribe($"{Module}.{Name}.DeviceData", () => _deviceData); DATA.Subscribe($"{Module}.{Name}.Pressure1Feedback", () => _aiValueSensorInput1.FloatValue); DATA.Subscribe($"{Module}.{Name}.Pressure2Feedback", () => _aiValueSensorInput2.FloatValue); DATA.Subscribe($"{Module}.{Name}.PositionFeedback", () => _aiPositionActualValue.FloatValue); DATA.Subscribe($"{Module}.{Name}.PositionSetPoint", () => _deviceData.PositionSetPoint); DATA.Subscribe($"{Module}.{Name}.PressureSetPoint", () => _deviceData.PressureSetPoint); DATA.Subscribe($"{Module}.{Name}.SlowRateSetPoint", () => _deviceData.SlowRateSetPoint); DATA.Subscribe($"{Module}.{Name}.SelectedControllerFeedback", () => SelectedControllerFeedback); DATA.Subscribe($"{Module}.{Name}.ModeFeedback", () => ModeFeedback); DATA.Subscribe($"{Module}.{Name}.ModeSetPoint", () => ModeSetPoint); DATA.Subscribe($"{Module}.{Name}.HomingStatus", () => HomingStatus); DATA.Subscribe($"{Module}.{Name}.IsError", () => IsError); DATA.Subscribe($"{Module}.{Name}.ValveStatusThreshold", () => ValveStatusThreshold); DATA.Subscribe($"{Module}.{Name}.SlowVacuumModeSetting", () => SlowVacuumModeSetting); DATA.Subscribe($"{Module}.{Name}.Interlock1", () => Interlock1); DATA.Subscribe($"{Module}.{Name}.Interlock2", () => Interlock2); DATA.Subscribe($"{Module}.{Name}.Interlock3", () => Interlock3); DATA.Subscribe($"{Module}.{Name}.InterlockConstantOfInterlock3", () => InterlockConstantOfInterlock3); DATA.Subscribe($"{Module}.{Name}.P1SensorOffsetSetting", () => P1SensorOffsetSetting); DATA.Subscribe($"{Module}.{Name}.PosMonOffsetSetting", () => PosMonOffsetSetting); //DATA.Subscribe($"{Module}.{Name}.IsSwitch", () => IsSwitch); //DATA.Subscribe($"{Module}.{Name}.SetSpeed", () => SetSpeed); //DATA.Subscribe($"{Module}.{Name}.MaxSpeed", () => MaxSpeed); //DATA.Subscribe($"{Module}.{Name}.IsReset", () => IsReset); //DATA.Subscribe($"{Module}.{Name}.ErrorTimer", () => ErrorTimer); //DATA.Subscribe($"{Module}.{Name}.CurrentSpeed", () => CurrentSpeed); //DATA.Subscribe($"{Module}.{Name}.Voltage", () => Voltage); //DATA.Subscribe($"{Module}.{Name}.Current", () => Current); OP.Subscribe($"{Module}.{Name}.SetParameters", (string cmd, object[] param) => { //command;pidTable;setValue;LowPressWait SetParameters(param); return true; }); OP.Subscribe($"{Module}.{Name}.SetManualParameters", (string cmd, object[] param) => { //command;pidTable;setValue;LowPressWait SetManualParameters(param); return true; }); OP.Subscribe($"{Module}.{Name}.SetUnit", (string cmd, object[] param) => { //command;pidTable;setValue;LowPressWait SetUnit(param); return true; }); OP.Subscribe($"{Module}.{Name}.SetUpload", (string cmd, object[] param) => { SetUpload(); return true; }); OP.Subscribe($"{Module}.{Name}.SetDownload", (string cmd, object[] param) => { SetDownload(param); return true; }); OP.Subscribe($"{Module}.{Name}.SetConfig", (string cmd, object[] param) => { //command;pidTable;setValue;LowPressWait SetConfig(param); return true; }); OP.Subscribe($"{Module}.{Name}.SetPID", (string cmd, object[] param) => { if (param != null && param.Length > 1) { int.TryParse(param[1].ToString(), out int controllerID); SetControllerParameters(param[0].ToString(), controllerID); } return true; }); ValveStatusThreshold = (float)SC.GetValue($"{Module}.{Name}.ValveStatusThreshold"); SlowVacuumModeSetting = (float)SC.GetValue($"{Module}.{Name}.SlowVacuumModeSetting"); Interlock1 = (float)SC.GetValue($"{Module}.{Name}.Interlock1"); Interlock2 = (float)SC.GetValue($"{Module}.{Name}.Interlock2"); Interlock3 = (float)SC.GetValue($"{Module}.{Name}.Interlock3"); InterlockConstantOfInterlock3 = (float)SC.GetValue($"{Module}.{Name}.InterlockConstantOfInterlock3"); P1SensorOffsetSetting = (float)SC.GetValue($"{Module}.{Name}.P1SensorOffsetSetting"); PosMonOffsetSetting = (float)SC.GetValue($"{Module}.{Name}.PosMonOffsetSetting"); return true; } private void SetUpload() { _unloadTimer.Restart(); _doAoDataReadSysConfig.SetPulseValue(true, 3000); } private void SetDownload(object[] param) { SetConfig(param); if (param != null && param.Length > 7) { float.TryParse(param[0].ToString(), out float value); _aoValveStatusThreshold.FloatValue = value; float.TryParse(param[1].ToString(), out value); _aoSlowVacuumModeSetting.FloatValue = value; float.TryParse(param[2].ToString(), out value); _aoInterlock1.FloatValue = value; float.TryParse(param[3].ToString(), out value); _aoInterlock2.FloatValue = value; float.TryParse(param[4].ToString(), out value); _aoInterlock3.FloatValue = value; float.TryParse(param[5].ToString(), out value); _aoInterlockConstantOfInterlock3.FloatValue = value; float.TryParse(param[6].ToString(), out value); _aoP1SensorOffsetSetting.FloatValue = value; float.TryParse(param[7].ToString(), out value); _aoPosMonOffsetSetting.FloatValue = value; } _doAoDataWriteSysConfig.SetPulseValue(true, 3000); } private void SetConfig(object[] param) { if(param != null && param.Length > 7) { float.TryParse(param[0].ToString(), out float value); ValveStatusThreshold = value; float.TryParse(param[1].ToString(), out value); SlowVacuumModeSetting = value; float.TryParse(param[2].ToString(), out value); Interlock1 = value; float.TryParse(param[3].ToString(), out value); Interlock2 = value; float.TryParse(param[4].ToString(), out value); Interlock3= value; float.TryParse(param[5].ToString(), out value); InterlockConstantOfInterlock3 = value; float.TryParse(param[6].ToString(), out value); P1SensorOffsetSetting = value; float.TryParse(param[7].ToString(), out value); PosMonOffsetSetting = value; } } public void Monitor() { if(!_isInit) { if (!_initTimer.IsRunning) _initTimer.Start(); if(_initTimer.ElapsedMilliseconds > 5 * 1000) { _initTimer.Stop(); _isInit = true; var pidTableName = SC.GetStringValue("PM1.APCPID"); int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out int controllerID); SetControllerParameters(pidTableName, controllerID); } } if(_valveAV71 == null) _valveAV71 = DEVICE.GetDevice($"{Module}.ValveAV71"); //if(_valveAV71 != null && Singleton.Instance.Modules.ContainsKey(ModuleName.PM1) && // !(Singleton.Instance.Modules[ModuleName.PM1] as PMModule).IsProcessing) //{ // _av71OpenTrig.CLK = _valveAV71.Status; // if (!_valveAV71.Status) // { // if (_aoSpecifyControlMode.FloatValue != (int)PressureControlMode.Close) // _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Close; // if (_deviceData.ModeSetPoint != (int)PressureControlMode.Close) // _deviceData.ModeSetPoint = (int)PressureControlMode.Close; // } // if(_av71OpenTrig.Q) // { // if (_aoSpecifyControlMode.FloatValue != (int)PressureControlMode.Open) // _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Open; // if (_deviceData.ModeSetPoint != (int)PressureControlMode.Open) // _deviceData.ModeSetPoint = (int)PressureControlMode.Open; // } //} if(_apcSetModeTimer.IsRunning && _apcSetModeTimer.ElapsedMilliseconds > _apcSetModeTimeOutSec * 1000) { APCSetModeAlarm.Set("APC set mode timeout"); } _deviceData.Pressure1Feedback = _aiValueSensorInput1.FloatValue; _deviceData.Pressure2Feedback = _aiValueSensorInput2.FloatValue; _deviceData.SelectedControllerFeedback = SelectedControllerFeedback; _deviceData.PositionFeedback = _aiPositionActualValue.FloatValue; _deviceData.ModeFeedback = ModeFeedback; _deviceData.HomingStatus = HomingStatus; _deviceData.PressureFeedback = GetPressure(); var hardError1 = _aiErrorStatus1.FloatValue > 0 ? "Active manufacturer Error Details (Device Management)" : ""; var hardError2 = _aiErrorStatus2.FloatValue > 0 ? "Active manufacturer Error Details(Sensor Input1))" : ""; var hardError3 = _aiErrorStatus3.FloatValue > 0 ? "Active manufacturer Error Details (Sensor Input2)" : ""; var hardError4 = _aiErrorStatus4.FloatValue > 0 ? "Active manufacturer Error Details (Valve)" : ""; if (!string.IsNullOrEmpty(hardError1) || !string.IsNullOrEmpty(hardError2) || !string.IsNullOrEmpty(hardError3) || !string.IsNullOrEmpty(hardError4)) { var status = !string.IsNullOrEmpty(hardError1) ? hardError1 : ""; status += !string.IsNullOrEmpty(status) ? !string.IsNullOrEmpty(hardError2) ? $"----{hardError2}" : "" : hardError2; status += !string.IsNullOrEmpty(status) ? !string.IsNullOrEmpty(hardError3) ? $"----{hardError3}" : "" : hardError3; status += !string.IsNullOrEmpty(status) ? !string.IsNullOrEmpty(hardError4) ? $"----{hardError4}" : "" : hardError4; _deviceData.HardError = status; IsError = true; } else { IsError = false; _deviceData.HardError = ""; } switch ((int)(_aiHomeStatus.FloatValue + 0.0001)) { case 0: _deviceData.HomeStatusDisplay = "Homing not started"; break; case 1: _deviceData.HomeStatusDisplay = "Homing interrupted"; break; case 2: _deviceData.HomeStatusDisplay = "Homing completed-no error"; break; case 3: _deviceData.HomeStatusDisplay = "Homing completed-error20"; break; case 4: _deviceData.HomeStatusDisplay = "Homing in progress"; break; default: _deviceData.HomeStatusDisplay = ""; break; } if (_readConfigTimer != null && _readConfigTimer.IsRunning && _readConfigTimer.ElapsedMilliseconds > 3000) { _readConfigTimer.Stop(); _doAoDataReadCusConfig.SetPulseValue(true, 3000); } } public void Reset() { //APCSetModeAlarm.Reset(); } public void SetUnit(object[] param) { if ((string)param[0] == "Pa") { _doVGUnit.SetValue(true, out _); } else { _doVGUnit.SetValue(false, out _); } } public void Terminate() { _valveAV71.TurnValve(false, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Close; _deviceData.ModeSetPoint = (int)PressureControlMode.Close; } private float GetPressure() { if (_deviceData.ModeFeedback == (int)(PressureControlMode.Press1Control)) return _aiValueSensorInput1.FloatValue; if (_deviceData.ModeFeedback == (int)(PressureControlMode.Press2Control)) return _aiValueSensorInput2.FloatValue; return _aiValueSensorInput2.FloatValue > SC.GetValue("PM1.APC.VG1.PressureScale") ? _aiValueSensorInput2.FloatValue : _aiValueSensorInput1.FloatValue; } private void SetParameters(object[] param) { if (param == null || param.Length < 1) { EV.PostWarningLog(Module, $"Invalid APC set parameter"); return; } var paras = param[0].ToString().Split(';'); if (paras.Length < 11) { EV.PostWarningLog(Module, $"Invalid APC set parameter"); return; } var command = paras[0]; var pidTables = paras[1].Split(','); string pidTableName = ""; int controllerID = 0; _deviceData.CommandSetPoint = command; IsNeedWaitComplete = false; if (command == "Press" || command == "Press2") { if (pidTables.Length < 2) { pidTableName = SC.GetStringValue("PM1.APCPID"); int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out controllerID); } else { pidTableName = string.IsNullOrEmpty(pidTables[0]) ? paras[10] : pidTables[0]; int.TryParse(pidTables[1], out controllerID); } } float setValue = 0; float.TryParse(paras[2], out float pressreValue); float.TryParse(paras[3], out float slowVacSet); float.TryParse(paras[4], out float valveAngleSet); bool.TryParse(paras[5], out _isWait); float.TryParse(paras[6], out _waitLow); float.TryParse(paras[7], out _waitHigh); var waitUnit = paras[8].ToString(); float.TryParse(paras[9], out float waitPress); var recipePIDTableName = paras[10].ToString(); var av71 = paras[11].ToString().ToLower();//open,close switch (command) { case "Press": case "Press2": setValue = pressreValue; IsNeedWaitComplete = _isWait; break; case "Slow Vac": setValue = slowVacSet; break; case "Valve Angle": setValue = valveAngleSet; IsNeedWaitComplete = _isWait; if (_waitLow == 0 || _waitHigh == 0) IsNeedWaitComplete = false;//_waitLow,_waitHigh为0不能wait if (waitUnit == "%") { _waitLow = setValue - _waitLow;//角度的要算出范围 _waitHigh = setValue + _waitHigh;//角度的要算出范围 } if (waitUnit == "%d") { //_waitLow,_waitHigh的设定本身就是范围 } break; case "WaitPressDown1": case "WaitPressDown2": case "WaitPressUp1": case "WaitPressUp2": setValue = waitPress; IsNeedWaitComplete = true; break; } _deviceData.SetPoint = setValue; _deviceData.PIDTable = $"{controllerID}:{paras[10]}"; _deviceData.LowPressWaitSetPoint = paras[3]; if(av71 == "close") { //av71 close,就设置为close _valveAV71.TurnValve(false, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Close; _deviceData.ModeSetPoint = (int)PressureControlMode.Close; _apcSetModeTimer.Stop(); } else { if (_deviceData.Pressure2Feedback >= 10) { if (command.ToLower() == "none" || command == "") _apcSetModeTimer.Restart(); else _apcSetModeTimer.Stop(); } else { _apcSetModeTimer.Stop(); if (command.ToLower() == "none" || command == "") command = "Full Open"; } if (command.ToLower() == "none") return; SetCommandParameters(command, setValue, pidTableName, controllerID, recipePIDTableName); } } private void SetManualParameters(object[] param) { if(param == null || param.Length < 1) { EV.PostWarningLog(Module, $"Invalid APC set parameter"); return; } var paras = param[0].ToString().Split(';'); if(paras.Length < 4) { EV.PostWarningLog(Module, $"Invalid APC set parameter"); return; } var command = paras[0]; var pidTables = paras[1].Split(','); string pidTableName = ""; int controllerID = 0; bool av71 = _valveAV71.Status; if (paras.Length > 4) bool.TryParse(paras[4], out av71); //小于 10 torr, full open或者根据设定的模式 //大于10 torr,5秒内需要设定的模式 if (av71) { if (_deviceData.Pressure2Feedback >= 10) { if (command.ToLower() == "none" || command == "") _apcSetModeTimer.Restart(); else _apcSetModeTimer.Stop(); } else { _apcSetModeTimer.Stop(); if (command.ToLower() == "none" || command == "") command = "Full Open"; } } else { command = "Full Close"; _apcSetModeTimer.Stop(); } if (command.ToLower() == "none") return; if (command == "Press" || command == "Press2") { if (pidTables.Length < 2) { pidTableName = SC.GetStringValue("PM1.APCPID"); int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out controllerID); } else { pidTableName = pidTables[0]; int.TryParse(pidTables[1], out controllerID); } } float.TryParse(paras[2], out float setValue); _deviceData.SetPoint = setValue; _deviceData.CommandSetPoint = command; _deviceData.PIDTable = $"{controllerID}:{pidTableName}"; _deviceData.LowPressWaitSetPoint = paras[3]; SetCommandParameters(command, setValue, pidTableName, controllerID); } private void SetCommandParameters(string command, float setValue, string pidTableName, int controllerID, string recipePIDTableName="") { LOG.Write($"APC command={command}, setpoint={setValue}, Controller ID={controllerID}, PID={pidTableName}"); switch (command) { case "Press": _valveAV71.TurnValve(true, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Press1Control; _aoSpecifyTargetVacuumPressureControl.FloatValue = setValue; SetControllerParameters(pidTableName, controllerID, recipePIDTableName); _aoControllerModeSelect.FloatValue = controllerID; _deviceData.ModeSetPoint = (int)PressureControlMode.Press1Control; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; _deviceData.PressureSetPoint = setValue; break; case "Press2": _valveAV71.TurnValve(true, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Press2Control; _aoSpecifyTargetVacuumPressureControl.FloatValue = setValue; SetControllerParameters(pidTableName, controllerID, recipePIDTableName); _aoControllerModeSelect.FloatValue = controllerID; _deviceData.ModeSetPoint = (int)PressureControlMode.Press2Control; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; _deviceData.PressureSetPoint = setValue; break; case "Slow Vac": _valveAV71.TurnValve(true, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.SlowVacuum; _aoSlowVacuumRate.FloatValue = setValue; _aoSlowVacuumTargetPressure.FloatValue = 0; _deviceData.ModeSetPoint = (int)PressureControlMode.SlowVacuum; SetSlowVacParameters(pidTableName); _deviceData.SlowRateSetPoint = setValue; break; case "Valve Angle": _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.PositionControl; _aoSpecifyTargetOpeningForValveOpeningControl.FloatValue = setValue; _deviceData.ModeSetPoint = (int)PressureControlMode.PositionControl; _deviceData.PositionSetPoint = setValue; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; break; case "Full Open": _valveAV71.TurnValve(true, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Open; _deviceData.ModeSetPoint = (int)PressureControlMode.Open; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; break; case "Full Close": _valveAV71.TurnValve(false, out _); _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Close; _deviceData.ModeSetPoint = (int)PressureControlMode.Close; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; break; case "Hold": _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Hold; _deviceData.ModeSetPoint = (int)PressureControlMode.Hold; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; break; case "Home": _aoSpecifyControlMode.FloatValue = (int)PressureControlMode.Homing; _deviceData.ModeSetPoint = (int)PressureControlMode.Homing; _aoSlowVacuumRate.FloatValue = 0; _aoSlowVacuumTargetPressure.FloatValue = 0; break; case "WaitPressUp1": //wait: sensor 1的压力小于basePressure _basePressure = setValue; _aoSlowVacuumTargetPressure.FloatValue = setValue; break; case "WaitPressDown1": //wait: sensor 1的压力大于basePressure _basePressure = setValue; _aoSlowVacuumTargetPressure.FloatValue = setValue; break; case "WaitPressUp2": //wait: sensor 2的压力小于basePressure _basePressure = setValue; _aoSlowVacuumTargetPressure.FloatValue = setValue; break; case "WaitPressDown2": //wait: sensor 2的压力大于basePressure _basePressure = setValue; _aoSlowVacuumTargetPressure.FloatValue = setValue; break; case "Zero Set": //offset cancle break; case "Cancel Zero": //cancle Zero Set break; } } private void SetSlowVacParameters(string fileNameAndPath) { if (string.IsNullOrEmpty(fileNameAndPath)) { fileNameAndPath = SC.GetStringValue("PM1.APCPID"); } if (!File.Exists($"{PathManager.GetParameterDir()}\\{fileNameAndPath}.rcp")) { fileNameAndPath = SC.GetStringValue("PM1.APCPID"); } var para = fileNameAndPath.Split('\\').ToList().Skip(2);//"Parameter\\APCPID" if (para == null) { EV.PostWarningLog(Module, $"{fileNameAndPath} APC PID name is empty"); return; } var fileName = string.Join("\\", para.ToArray()); var content = ParameterFileManager.Instance.LoadParameter("Parameter\\APCPID", fileName, false); if (string.IsNullOrEmpty(content)) { EV.PostWarningLog(Module, $"{fileNameAndPath} APC PID file is empty"); return; } var doc = new XmlDocument(); doc.LoadXml(content); XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData"); if (nodeSteps == null) { EV.PostWarningLog(Module, $"Invalid APC PID file {fileNameAndPath}"); return; } foreach (var step in nodeSteps) { XmlElement stepNode = step as XmlElement; float value = 0; var hasSetValue = false; foreach (XmlAttribute att in stepNode.Attributes) { switch (att.Name.ToUpper()) { case "P": float.TryParse(att.Value, out value); _aoSlowVacuumP.FloatValue = value; break; case "I": float.TryParse(att.Value, out value); _aoSlowVacuumI.FloatValue = value; break; case "D": float.TryParse(att.Value, out value); _aoSlowVacuumD.FloatValue = value; break; case "A": float.TryParse(att.Value, out value); _aoSlowVacuumA.FloatValue = value; break; } hasSetValue = true; } _doAoDataWriteCusConfig.SetPulseValue(true, 3000); _readConfigTimer.Restart(); if (hasSetValue) return; } if (SC.GetStringValue("PM1.APCPID") != fileNameAndPath) SC.SetItemValueFromString("PM1.APCPID", fileNameAndPath); } private void SetControllerParameters(string fileNameAndPath, int controllerID, string recipePIDTableName = "") { //var defaultPID = SC.GetStringValue("PM1.APCPID"); if(string.IsNullOrEmpty(fileNameAndPath)) { fileNameAndPath = SC.GetStringValue("PM1.APCPID"); } if (!File.Exists($"{PathManager.GetParameterDir()}\\{fileNameAndPath}.rcp")) { fileNameAndPath = SC.GetStringValue("PM1.APCPID"); } var para = fileNameAndPath.Split('\\').ToList().Skip(2);//"Parameter\\APCPID" if (para == null) { EV.PostWarningLog(Module, $"{fileNameAndPath} APC PID name is empty"); return; } var fileName = string.Join( "\\", para.ToArray()); if (!string.IsNullOrEmpty(recipePIDTableName)) fileName = recipePIDTableName; if(controllerID <= 0) { int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out controllerID); } _deviceData.PIDTable = $"{controllerID}:{fileName}"; var content = ParameterFileManager.Instance.LoadParameter("Parameter\\APCPID", fileName, false); if (string.IsNullOrEmpty(content)) { EV.PostWarningLog(Module, $"{fileNameAndPath} APC PID file is empty"); return; } var doc = new XmlDocument(); doc.LoadXml(content); XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step"); if (nodeSteps == null) nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step"); if(nodeSteps == null) { EV.PostWarningLog(Module, $"Invalid APC PID file {fileNameAndPath}"); return; } Dictionary dic = new Dictionary(); float p = 0; float i = 0; float d = 0; float a = 0; float ch = 0; float cl = 0; float offset = 0; foreach (var step in nodeSteps) { XmlElement stepNode = step as XmlElement; var parameters = new Dictionary(); foreach (XmlAttribute att in stepNode.Attributes) { parameters.Add(att.Name, att.Value); } int.TryParse(parameters["StepNo"], out int no); float.TryParse(parameters["P"], out p); float.TryParse(parameters["I"], out i); float.TryParse(parameters["D"], out d); float.TryParse(parameters["a"], out a); float.TryParse(parameters["offset"], out offset); float.TryParse(parameters["CH"], out ch); float.TryParse(parameters["CL"], out cl); if(dic.ContainsKey(no)) { EV.PostWarningLog(Module, $"Invalid APC PID file {fileNameAndPath}, duplicate no={no}"); return; } dic.Add(no, new ControllerParameter() { No = no, Name = parameters["Name"], P = p, I = i, D = d, A = a, Offset = offset, CH = ch, CL = cl, }); } if (!dic.ContainsKey(controllerID)) { int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out controllerID); } if (!dic.ContainsKey(controllerID)) return; p = dic[controllerID].P; i = dic[controllerID].I; d = dic[controllerID].D; a = dic[controllerID].A; ch = dic[controllerID].CH; cl = dic[controllerID].CL; offset = dic[controllerID].Offset; switch(controllerID) { case 1: _aoController1P.FloatValue = p; _aoController1I.FloatValue = i; _aoController1D.FloatValue = d; _aoController1A.FloatValue = a; _aoController1CH.FloatValue = ch; _aoController1CL.FloatValue = cl; _aoController1Offset.FloatValue = offset; break; case 2: _aoController2P.FloatValue = p; _aoController2I.FloatValue = i; _aoController2D.FloatValue = d; _aoController2A.FloatValue = a; _aoController2CH.FloatValue = ch; _aoController2CL.FloatValue = cl; _aoController2Offset.FloatValue = offset; break; case 3: _aoController3P.FloatValue = p; _aoController3I.FloatValue = i; _aoController3D.FloatValue = d; _aoController3A.FloatValue = a; _aoController3CH.FloatValue = ch; _aoController3CL.FloatValue = cl; _aoController3Offset.FloatValue = offset; break; case 4: _aoController4P.FloatValue = p; _aoController4I.FloatValue = i; _aoController4D.FloatValue = d; _aoController4A.FloatValue = a; _aoController4CH.FloatValue = ch; _aoController4CL.FloatValue = cl; _aoController4Offset.FloatValue = offset; break; case 5: _aoController5P.FloatValue = p; _aoController5I.FloatValue = i; _aoController5D.FloatValue = d; _aoController5A.FloatValue = a; _aoController5CH.FloatValue = ch; _aoController5CL.FloatValue = cl; _aoController5Offset.FloatValue = offset; break; case 6: _aoController6P.FloatValue = p; _aoController6I.FloatValue = i; _aoController6D.FloatValue = d; _aoController6A.FloatValue = a; _aoController6CH.FloatValue = ch; _aoController6CL.FloatValue = cl; _aoController6Offset.FloatValue = offset; break; case 7: _aoController7P.FloatValue = p; _aoController7I.FloatValue = i; _aoController7D.FloatValue = d; _aoController7A.FloatValue = a; _aoController7CH.FloatValue = ch; _aoController7CL.FloatValue = cl; _aoController7Offset.FloatValue = offset; break; case 8: _aoController8P.FloatValue = p; _aoController8I.FloatValue = i; _aoController8D.FloatValue = d; _aoController8A.FloatValue = a; _aoController8CH.FloatValue = ch; _aoController8CL.FloatValue = cl; _aoController8Offset.FloatValue = offset; break; case 9: _aoController9P.FloatValue = p; _aoController9I.FloatValue = i; _aoController9D.FloatValue = d; _aoController9A.FloatValue = a; _aoController9CH.FloatValue = ch; _aoController9CL.FloatValue = cl; _aoController9Offset.FloatValue = offset; break; case 10: _aoController10P.FloatValue = p; _aoController10I.FloatValue = i; _aoController10D.FloatValue = d; _aoController10A.FloatValue = a; _aoController10CH.FloatValue = ch; _aoController10CL.FloatValue = cl; _aoController10Offset.FloatValue = offset; break; } _doAoDataWriteCusConfig.SetPulseValue(true, 3000); _readConfigTimer.Restart(); if (SC.GetStringValue("PM1.APCPID") != fileNameAndPath) SC.SetItemValueFromString("PM1.APCPID", fileNameAndPath); if (SC.GetStringValue("PM1.APCPIDControllerID") != controllerID.ToString()) SC.SetItemValueFromString("PM1.APCPIDControllerID", controllerID.ToString()); } public bool CheckWaitCondition(out string reason) { reason = ""; if(IsNeedWaitComplete) { var command = _deviceData.CommandSetPoint; var setValue = _deviceData.SetPoint; switch (command) { case "Press": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Press1Control && ((_deviceData.Pressure1Feedback > _deviceData.PressureSetPoint - _waitLow && _deviceData.Pressure1Feedback < _deviceData.PressureSetPoint + _waitHigh) || (_waitLow <= 0 && _waitHigh <= 0))) { return true; } else { reason = $"press1 feedback={_deviceData.Pressure1Feedback}, wait condition is ({_deviceData.PressureSetPoint - _waitLow}, {_deviceData.PressureSetPoint + _waitHigh})"; } break; case "Press2": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Press2Control && ((_deviceData.Pressure2Feedback > _deviceData.PressureSetPoint - _waitLow && _deviceData.Pressure2Feedback < _deviceData.PressureSetPoint + _waitHigh )|| (_waitLow <= 0 && _waitHigh <= 0))) { return true; } else { reason = $"press2 feedback={_deviceData.Pressure2Feedback}, wait condition is ({_deviceData.PressureSetPoint - _waitLow}, {_deviceData.PressureSetPoint + _waitHigh})"; } break; case "Slow Vac": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.SlowVacuum) { return true; } else { reason = $"slow vac wait"; } break; case "Valve Angle": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.PositionControl && ((_deviceData.PositionFeedback > _waitLow && _deviceData.PositionFeedback < _waitHigh )|| (_waitLow <= 0 && _waitHigh <= 0))) { return true; } else { reason = $"position feedback={_deviceData.PositionFeedback}, wait condition is ({_waitLow}, {_waitHigh})"; } break; case "Full Open": if(_deviceData.ModeSetPoint== _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Open) { return true; } else { reason = $"full open wait"; } break; case "Full Close": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Close) { return true; } else { reason = $"full close wait"; } break; case "Hold": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Hold) { return true; } else { reason = $"hold wait"; } break; case "Home": if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Homing) { return true; } else { reason = $"home wait"; } break; case "WaitPressUp1": //wait: sensor 1的压力大于等于basePressure if (_deviceData.Pressure1Feedback >= _basePressure) { return true; } else { reason = $"WaitPressUp1 press1 feedback={_deviceData.Pressure1Feedback} < basePressure={_basePressure}"; } break; case "WaitPressDown1": //wait: sensor 1的压力小于等于basePressure if (_deviceData.Pressure1Feedback <= _basePressure) { return true; } else { reason = $"WaitPressDown1 press1 feedback={_deviceData.Pressure1Feedback} > basePressure={_basePressure}"; } break; case "WaitPressUp2": //wait: sensor 2的压力大于等于basePressure if (_deviceData.Pressure2Feedback >= _basePressure) { return true; } else { reason = $"WaitPressUp2 press2 feedback={_deviceData.Pressure2Feedback} < basePressure={_basePressure}"; } break; case "WaitPressDown2": //wait: sensor 2的压力小于等于basePressure if (_deviceData.Pressure2Feedback <= _basePressure) { return true; } else { reason = $"WaitPressDown2 press2 feedback={_deviceData.Pressure2Feedback} > basePressure={_basePressure}"; } break; case "Zero Set": //offset cancle break; case "Cancel Zero": //cancle Zero Set break; } return false; } else { return true; } } struct ControllerParameter { public int No { get; set; } public string Name { get; set; } public float P { get; set; } public float I { get; set; } public float D { get; set; } public float A { get; set; } public float Offset { get; set; } public float CH { get; set; } public float CL { get; set; } } } }