| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574 | 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<IoAPC>($"{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<double>($"{Module}.{Name}.ValveStatusThreshold");            SlowVacuumModeSetting = (float)SC.GetValue<double>($"{Module}.{Name}.SlowVacuumModeSetting");            Interlock1 = (float)SC.GetValue<double>($"{Module}.{Name}.Interlock1");            Interlock2 = (float)SC.GetValue<double>($"{Module}.{Name}.Interlock2");            Interlock3 = (float)SC.GetValue<double>($"{Module}.{Name}.Interlock3");            InterlockConstantOfInterlock3 = (float)SC.GetValue<double>($"{Module}.{Name}.InterlockConstantOfInterlock3");            P1SensorOffsetSetting = (float)SC.GetValue<double>($"{Module}.{Name}.P1SensorOffsetSetting");            PosMonOffsetSetting = (float)SC.GetValue<double>($"{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<IoValve>($"{Module}.ValveAV71");            //if(_valveAV71 != null && Singleton<EquipmentManager>.Instance.Modules.ContainsKey(ModuleName.PM1) &&            //    !(Singleton<EquipmentManager>.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<double>("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<int, ControllerParameter> dic = new Dictionary<int, ControllerParameter>();            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<string, string>();                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; }        }    }}
 |