using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using Aitex.Core.WCF;
using MECF.Framework.Common.PLC;
using SicSimulator.Views;

namespace SicSimulator.Instances
{
    public class SimulatorSystem : Singleton<SimulatorSystem>
    {
        private PeriodicJob _thread;
        private readonly Random _rnd = new();
        private const float WaterTempBase = 30.0f;

        public SimulatorSystem()
        {

        }

        public void Initialize()
        {
            SetDefaultValue("PM1");
            SetDefaultValue("PM2");
            SetTMDefaultValue("TM");

            //Singleton<DataManager>.Instance.Initialize(false);

            WcfServiceManager.Instance.Initialize(new Type[] { typeof(SimulatorAdsPlcService) });

            _thread = new PeriodicJob(200, OnMonitor, nameof(SimulatorSystem), true);
        }


        private void SetTMDefaultValue(string mod)
        {
            IO.DO["DO_LoadLidClose"].Value = true;

            IO.DI["DI_LoadLidLocked"].Value = true;
            IO.DI["DI_UnloadStationLifterCYDown"].Value = true;
            IO.DI["DI_LoadWafeCYOpened"].Value = true;
            IO.DI["DI_LoadTrayCYOpend"].Value = true;
            IO.DI["DI_UnloadStationWaferCYOpened"].Value = true;
            IO.DI["DI_LoadLeftGateINTK"].Value = false;
            IO.DI["DI_LoadRightGateINTK"].Value = false;

            IO.DI["DI_LdRotationMoveDone"].Value = true;

            IO.DI["DI_TMDryPump1Alarm"].Value = true;
            IO.DI["DI_TMDryPump1Warning"].Value = true;
            IO.DI["DI_TMDryPump1Running"].Value = true;

            IO.DI["DI_TMDryPump2Alarm"].Value = true;
            IO.DI["DI_TMDryPump2Warning"].Value = true;
            IO.DI["DI_TMDryPump2Running"].Value = true;

            //IO.DI["DI_TMDryPump2Alarm"].Value = true;
            //IO.DI["DI_TMDryPump2Warning"].Value = true;
            //IO.DI["DI_TMDryPump2Running"].Value = true;



            IO.DI["DI_RobotOnBackPos"].Value = true;

            IO.AI["AI_TMPressure1"].Value = 300;
            IO.AI["AI_LoadPressure"].Value = 1020;
            IO.AI["AI_UnloadPressure"].Value = 300;
            IO.DI["DI_TMPressure1VAC"].Value = true;

            //SlitValve
            IO.DI["DI_LoadDoorClosed"].Value = true;
            IO.DI["DI_ReactorADoorClosed"].Value = true;
            IO.DI["DI_ReactorBDoorClosed"].Value = true;
            IO.DI["DI_UnloadStationDoorClosed"].Value = true;
            IO.DI["DI_BufferStationDoorClosed"].Value = true;
            IO.DI["DI_UnloadSubStationDoorClosed"].Value = true;
            IO.DI["DI_LoadLSideDoorClosed"].Value = true;
            IO.DI["DI_LoadRSideDoorClosed"].Value = true;
            IO.DI["DI_LoadDoorOpened"].Value = false;
            IO.DI["DI_ReactorADoorOpened"].Value = false;
            IO.DI["DI_ReactorBDoorOpened"].Value = false;
            IO.DI["DI_BufferStationDoorOpened"].Value = false;
            IO.DI["DI_UnloadStationDoorOpened"].Value = false;
            IO.DI["DI_UnloadSubStationDoorOpened"].Value = false;
            IO.DI["DI_LoadLSideDoorOpened"].Value = false;
            IO.DI["DI_LoadRSideDoorOpened"].Value = false;

            //Lid
            IO.DI["DI_TMLidClosed"].Value = true;
            IO.DI["DI_LoadLidClosed"].Value = true;
            IO.DI["DI_BufferStationLidClosed"].Value = true;
            IO.DI["DI_UnloadStationLidClosed"].Value = true;

            IO.DI["DI_WaferCassetLeftInch6"].Value = true;
            IO.DI["DI_WaferCassetRightInch6"].Value = true;
            IO.DI["DI_TrayCassetInch6"].Value = true;

            IO.DI["DI_LdRotationBusy"].Value = false;

            IO.DO["DO_LdRotationServoOn"].Value = true;
            IO.DI["DI_LdRotationServoOn"].Value = true;

            IO.DO["DO_LoadLidLock"].Value = true;
            IO.DO["DO_LoadLidUnlock"].Value = true;
            
        }

        private void SetDefaultValue(string mod)
        {
            SetWaterTemp(mod);

            IO.DI[$"{mod}.DI_ConfinementRingDone"].Value = true;
            IO.DI[$"{mod}.DI_DryPumpAlarm"].Value = true;
            IO.DI[$"{mod}.DI_DryPump1Warning"].Value = true;
            IO.DI[$"{mod}.DI_DryPump1Running"].Value = true;

            IO.DI[$"{mod}.DI_DryPump2Alarm"].Value = true;
            IO.DI[$"{mod}.DI_DryPump2Warning"].Value = true;
            IO.DI[$"{mod}.DI_DryPump2Running"].Value = true;

            IO.DI[$"{mod}.DI_ServoReady"].Value = true;
            IO.AI[$"{mod}.AI_ForelinePress"].Value = 300;
            IO.AI[$"{mod}.AI_ChamPress"].Value = 300;
            IO.AI[$"{mod}.AI_ActualPressure"].Value = 300;
            IO.DI[$"{mod}.DI_EPV2-1FB"].Value = true;

            IO.DI[$"{mod}.DI_ChamPressAboveATMSW"].Value = true;
            IO.DI[$"{mod}.DI_HeaterTempUpLimitSW"].Value = false;
            IO.DI[$"{mod}.DI_ChamTopFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_DryPump1Running"].Value = true;


            IO.DI[$"{mod}.DI_ChamLidPushButtonLocal"].Value = true;
            IO.DI[$"{mod}.DI_ChamMoveBodyDown"].Value = true;
            IO.DI[$"{mod}.DI_ChamMoveBodyFront"].Value = true;
            IO.DI[$"{mod}.DI_ChamMoveBodyUpLatchFW"].Value = false;
            IO.DI[$"{mod}.DI_ChamMoveBodyEndLatchBW"].Value = true;

            IO.DI[$"{mod}.DI_SHLidClosed"].Value = true;
            IO.DI[$"{mod}.DI_MiddleLidClosed"].Value = true;
            IO.DI[$"{mod}.DI_SHLidTighten"].Value = true;
            IO.DI[$"{mod}.DI_MiddleLidTighten"].Value = true;

            IO.DI[$"{mod}.DI_SHLidSwingLock"].Value = true;
            IO.DI[$"{mod}.DI_MiddleLidSwingLock"].Value = true;


            IO.DI[$"{mod}.DI_SHGasConnectorLoosen"].Value = false;
            IO.DI[$"{mod}.DI_SHGasConnectorTighten"].Value = true;
            IO.DO[$"{mod}.DO_CleanRoutineSucceed"].Value = true;
            IO.DI[$"{mod}.DI_PSUEnableFB"].Value = true;

            IO.AO[$"{mod}.AO_ValveModeSetpoint"].Value = (float)2;

            IO.DI[$"{mod}.DI_ChamLidClosed"].Value = true;
            IO.DI[$"{mod}.DI_ChamCabDoorClosed"].Value = true;
            IO.DI[$"{mod}.DI_ChamPressAboveATMSW"].Value = true;
            IO.DI[$"{mod}.DI_ChamAtSafeProcessPressSW"].Value = false;
            IO.DI[$"{mod}.DI_DORPressVacSW"].Value = true;
            IO.DI[$"{mod}.DI_DORPressATMSW"].Value = false;
            IO.DI[$"{mod}.DI_HeaterTempLowLimitSW"].Value = true;
            IO.DI[$"{mod}.DI_ConfinementRingUp"].Value = true;
            IO.DI[$"{mod}.DI_ConfinementRingDown"].Value = false;
            IO.DI[$"{mod}.DI_SHFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_ChamTopFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_ChamMiddleFlow1SW"].Value = true;
            IO.DI[$"{mod}.DI_ChamBottomFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_PowerRod1FlowSW"].Value = true;
            IO.DI[$"{mod}.DI_PowerRod2FlowSW"].Value = true;
            IO.DI[$"{mod}.DI_Foreline2FlowSW"].Value = true;
            IO.DI[$"{mod}.DI_ElectrodeWFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_TMPumpFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_Foreline1FlowSW"].Value = true;
            IO.DI[$"{mod}.DI_TransformerFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_GBH2DetectorSW"].Value = true;
            IO.DI[$"{mod}.DI_GBHCLDetectorSW"].Value = true;
            IO.DI[$"{mod}.DI_GBDoorClosed"].Value = true;
            IO.DI[$"{mod}.DI_PumpExhaustPressSW"].Value = true;
            IO.DI[$"{mod}.DI_PMATMSW"].Value = true;
            IO.DI[$"{mod}.DI_ScrubberIntlkSW"].Value = true;
            IO.DI[$"{mod}.DI_FacilityIntlkSW"].Value = true;
            IO.DI[$"{mod}.DI_PowerRackWaterLeakSW"].Value = true;


            #region TC

            //IO.AI[$"{mod}.AI_L1WorkingOP"].Value = 10;
            //IO.AI[$"{mod}.AI_L2WorkingOP"].Value = 10;
            //IO.AI[$"{mod}.AI_L3WorkingOP"].Value = 10;
            //IO.AI[$"{mod}.AI_L1PV"].Value = 20;
            //IO.AI[$"{mod}.AI_L2PV"].Value = 20;
            //IO.AI[$"{mod}.AI_L3PV"].Value = 20;
            //IO.AI[$"{mod}.AI_L1TempHighAlarm"].Value = 30;
            //IO.AI[$"{mod}.AI_L2TempHighAlarm"].Value = 30;
            //IO.AI[$"{mod}.AI_L3TempHighAlarm"].Value = 30;
            //IO.AI[$"{mod}.AI_L1TempLowAlarm"].Value = 25;
            //IO.AI[$"{mod}.AI_L2TempLowAlarm"].Value = 25;
            //IO.AI[$"{mod}.AI_L3TempLowAlarm"].Value = 25;

            //IO.AO[$"{mod}.AO_L1LoopMode"].Value = 1;
            //IO.AO[$"{mod}.AO_L2LoopMode"].Value = 1;
            //IO.AO[$"{mod}.AO_L3LoopMode"].Value = 1;
            //IO.AO[$"{mod}.AO_L1TargetSP"].Value = 20;
            //IO.AO[$"{mod}.AO_L2TargetSP"].Value = 20;
            //IO.AO[$"{mod}.AO_L3TargetSP"].Value = 20;
            //IO.AO[$"{mod}.AO_L1TargetOP"].Value = 30;
            //IO.AO[$"{mod}.AO_L2TargetOP"].Value = 30;
            //IO.AO[$"{mod}.AO_L3TargetOP"].Value = 30;
            //IO.AO[$"{mod}.AO_L1IPCST"].Value = 40;
            //IO.AO[$"{mod}.AO_L2IPCST"].Value = 40;
            //IO.AO[$"{mod}.AO_L3IPCST"].Value = 40;
            //IO.AO[$"{mod}.AO_L1IPCST"].Value = 70;
            //IO.AO[$"{mod}.AO_L2IPCST"].Value = 70;
            //IO.AO[$"{mod}.AO_L3IPCST"].Value = 70;
            //IO.AO[$"{mod}.AO_TCPyroMode"].Value = 1;
            //IO.AO[$"{mod}.AO_L1TempHighLimit"].Value = 90;
            //IO.AO[$"{mod}.AO_L2TempHighLimit"].Value = 90;
            //IO.AO[$"{mod}.AO_L3TempHighLimit"].Value = 90;
            //IO.AO[$"{mod}.AO_L1TempLowLimit"].Value = 80;
            //IO.AO[$"{mod}.AO_L2TempLowLimit"].Value = 80;
            //IO.AO[$"{mod}.AO_L3TempLowLimit"].Value = 80;

            //IO.AI[$"{mod}.AI_L1WorkingOP2"].Value = 10;
            //IO.AI[$"{mod}.AI_L2WorkingOP2"].Value = 10;
            //IO.AI[$"{mod}.AI_L3WorkingOP2"].Value = 10;
            //IO.AI[$"{mod}.AI_L1PV2"].Value = 20;
            //IO.AI[$"{mod}.AI_L2PV2"].Value = 20;
            //IO.AI[$"{mod}.AI_L3PV2"].Value = 20;
            //IO.AI[$"{mod}.AI_L1TempHighAlarm2"].Value = 30;
            //IO.AI[$"{mod}.AI_L2TempHighAlarm2"].Value = 30;
            //IO.AI[$"{mod}.AI_L3TempHighAlarm2"].Value = 30;
            //IO.AI[$"{mod}.AI_L1TempLowAlarm2"].Value = 25;
            //IO.AI[$"{mod}.AI_L2TempLowAlarm2"].Value = 25;
            //IO.AI[$"{mod}.AI_L3TempLowAlarm2"].Value = 25;

            //IO.AO[$"{mod}.AO_L1LoopMode2"].Value = 1;
            //IO.AO[$"{mod}.AO_L2LoopMode2"].Value = 1;
            //IO.AO[$"{mod}.AO_L3LoopMode2"].Value = 1;
            //IO.AO[$"{mod}.AO_L1TargetSP2"].Value = 20;
            //IO.AO[$"{mod}.AO_L2TargetSP2"].Value = 20;
            //IO.AO[$"{mod}.AO_L3TargetSP2"].Value = 20;
            //IO.AO[$"{mod}.AO_L1TargetOP2"].Value = 30;
            //IO.AO[$"{mod}.AO_L2TargetOP2"].Value = 30;
            //IO.AO[$"{mod}.AO_L3TargetOP2"].Value = 30;
            //IO.AO[$"{mod}.AO_L1RecipeValue2"].Value = 40;
            //IO.AO[$"{mod}.AO_L2RecipeValue2"].Value = 40;
            //IO.AO[$"{mod}.AO_L3RecipeValue2"].Value = 40;
            //IO.AO[$"{mod}.AO_L1IPCST2"].Value = 70;
            //IO.AO[$"{mod}.AO_L2IPCST2"].Value = 70;
            //IO.AO[$"{mod}.AO_L3IPCST2"].Value = 70;
            //IO.AO[$"{mod}.AO_TCPyroMode2"].Value = 1;
            //IO.AO[$"{mod}.AO_L1TempHighLimit2"].Value = 90;
            //IO.AO[$"{mod}.AO_L2TempHighLimit2"].Value = 90;
            //IO.AO[$"{mod}.AO_L3TempHighLimit2"].Value = 90;
            //IO.AO[$"{mod}.AO_L1TempLowLimit2"].Value = 80;
            //IO.AO[$"{mod}.AO_L2TempLowLimit2"].Value = 80;
            //IO.AO[$"{mod}.AO_L3TempLowLimit2"].Value = 80;
            #endregion

            IO.DI[$"{mod}.DI_PMH2DetectorSW"].Value = true;
            IO.DI[$"{mod}.DI_ProcessStopSW"].Value = false;
            IO.DI[$"{mod}.DI_TransformerOTSW"].Value = false;
            IO.DI[$"{mod}.DI_GBWaterLeakSW"].Value = true;
            IO.DI[$"{mod}.DI_MainCBStatusSW"].Value = true;
            IO.DI[$"{mod}.DI_ReactorWaterLeakSW"].Value = true;
            IO.DI[$"{mod}.DI_ChamMiddleFlow1SW"].Value = true;
            IO.DI[$"{mod}.DI_ChamMiddleFlow2SW"].Value = true;
            IO.DI[$"{mod}.DI_PumpExhaustDPSW"].Value = true;
            IO.DI[$"{mod}.DI_Spare2FlowSW"].Value = true;
            IO.DI[$"{mod}.DI_Spare1FlowSW"].Value = true;

            IO.DI[$"{mod}.DI_H2PressureSW"].Value = true;
            IO.DI[$"{mod}.DI_TCSAlarm"].Value = true;
            IO.DI[$"{mod}.DI_GBExhaustDPSW"].Value = true;
            IO.DI[$"{mod}.DI_PMAExhaustDPSW"].Value = true;

            IO.DI[$"{mod}.DI_ServoDriverFaultSW"].Value = true;

            IO.DI[$"{mod}.DI_GN2InletPressSW"].Value = true;
            IO.DI[$"{mod}.DI_ArInletPressSW"].Value = true;
            IO.DI[$"{mod}.DI_FacilityWarningSW"].Value = true;

            IO.DI[$"{mod}.DI_GBNH3DetectorSW"].Value = true;
            IO.DI[$"{mod}.DI_PMNH3DetectorSW"].Value = true;

            //IO.DI[$"{mod}.DI_InletTotalTempHighSW"].Value = true;
            //IO.DI[$"{mod}.DI_DryPumpFlowSW"].Value = true;
            IO.DI[$"{mod}.DI_EMOStatusSW"].Value = true;

            IO.DO[$"{mod}.DO_UPSEnable"].Value = true;
            IO.DO[$"{mod}.DO_UPSLowBattery"].Value = true;
            IO.DI[$"{mod}.DI_SuspectorCheck"].Value = false;

            IO.DI[$"{mod}.DI_GasPipeTempCtrlAlarm"].Value = true;

            IO.DI[$"{mod}.DI_ConfinementRingServoOn"].Value = true;
            IO.DO[$"{mod}.DO_ConfinementRingServoOn"].Value = true;

            IO.DO[$"{mod}.DO_ReactorPressRisingRateFast"].Value = true;

            IO.DO[$"{mod}.DO_ChamMiddleFlow2Temp"].Value = true;
            IO.DO[$"{mod}.DO_SHFlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_ChamTopFlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_ChamMiddleFlow1Temp"].Value = true;

            IO.DO[$"{mod}.DO_ChamBottomFlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_SpareFlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_Spare1FlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_PowerRod1FlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_PowerRod2FlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_ElectrodeWFlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_Spare1FlowTemp"].Value = true;
            IO.DO[$"{mod}.DO_TransformerFlowTemp"].Value = true;

            IO.DO[$"{mod}.DO_HeaterEnable"].Value = true;
            IO.DO[$"{mod}.DO_EPV2"].Value = true;

            IO.DI[$"{mod}.DI_ReactorHCLDetectorSW"].Value = true;
        }

        private void SetWaterTemp(string mod)
        {
            #region Water Flow

            IO.AI[$"{mod}.AI_ChamMiddleFlow2Temp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_SHFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_ChamTopFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_ChamMiddleFlow1Temp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_ChamBottomFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_Foreline2FlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_PowerRod1FlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_PowerRod2FlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_Foreline1FlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_ElectrodeWFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_TMPumpFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_TransformerFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_Spare1Temp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_Spare2Temp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;
            IO.AI[$"{mod}.AI_SpareFlowTemp"].Value = (float)(WaterTempBase * _rnd.NextDouble()); ;

            #endregion
        }

        private bool OnMonitor()
        {
            try
            {
                MonitorPressureTM();
                MonitorPressureLoad();
                MonitorPressureUnLoad();
                MonitorSlitValveFlow();
                MonitorTMValve();

                MonitorPm("PM1");
                MonitorPm("PM2");
                MonitorValve("PM1");
                MonitorValve("PM2");

                MonitorFlowRamp("PM1");
                //MonitorFlowRamp("PM2");
                MonitorGasConnector("PM1");
                MonitorLid("PM1");
                MonitorLidSwing("PM1");
                MonitorConfinementRing("PM1");
                MonitorGasConnector("PM2");
                MonitorLid("PM2");
                MonitorLidSwing("PM2");
                MonitorConfinementRing("PM2");
                MonitorChamberMoveBody("PM1");
                MonitorChamberMoveBodyUp("PM1");
                MonitorHeater("PM1");
                MonitorRotation("PM1");
                MonitorChamberMoveBody("PM2");
                MonitorChamberMoveBodyUp("PM2");
                MonitorHeater("PM2");
                MonitorRotation("PM2");
            }
            catch (Exception e)
            {
                LOG.Write(e);
            }
            return true;
        }

        void MonitorFlowRamp(string pm)
        {
            var rampList = new List<Tuple<string, string>>
                            {
                                new Tuple<string, string>(
                                    "AI_M1",
                                    "AO_M1"
                                    ),
                                new Tuple<string, string>(
                                    "AI_M2",
                                    "AO_M2"
                                    ),
                                new Tuple<string, string>("AI_M3","AO_M3"),
                                new Tuple<string, string>("AI_M4","AO_M4"),
                                new Tuple<string, string>("AI_M5","AO_M5"),
                                new Tuple<string, string>("AI_M6","AO_M6"),
                                new Tuple<string, string>("AI_M7","AO_M7"),
                                new Tuple<string, string>("AI_M8","AO_M8"),
                                new Tuple<string, string>("AI_M9","AO_M9"),
                                new Tuple<string, string>("AI_M10","AO_M10"),
                                new Tuple<string, string>("AI_M11","AO_M11"),
                                new Tuple<string, string>("AI_M12","AO_M12"),
                                new Tuple<string, string>("AI_M13","AO_M13"),
                                new Tuple<string, string>("AI_M14","AO_M14"),
                                new Tuple<string, string>("AI_M15","AO_M15"),
                                new Tuple<string, string>("AI_M16","AO_M16"),
                                new Tuple<string, string>("AI_M17","AO_M17"),
                                new Tuple<string, string>("AI_M18","AO_M18"),
                                new Tuple<string, string>("AI_M19","AO_M19"),
                                new Tuple<string, string>("AI_M20","AO_M20"),
                                new Tuple<string, string>("AI_M22","AO_M22"),
                                new Tuple<string, string>("AI_M23","AO_M23"),
                                new Tuple<string, string>("AI_M25","AO_M25"),
                                new Tuple<string, string>("AI_M26","AO_M26"),
                                new Tuple<string, string>("AI_M27","AO_M27"),
                                new Tuple<string, string>("AI_M28","AO_M28"),
                                new Tuple<string, string>("AI_M29","AO_M29"),
                                new Tuple<string, string>("AI_M31","AO_M31"),
                                new Tuple<string, string>("AI_M32","AO_M32"),
                                new Tuple<string, string>("AI_M33","AO_M33"),

                                new Tuple<string, string>("AI_M35","AO_M35"),
                                new Tuple<string, string>("AI_M36","AO_M36"),
                                new Tuple<string, string>("AI_M37","AO_M37"),
                                new Tuple<string, string>("AI_M38","AO_M38"),

                                new Tuple<string, string>("AI_M40","AO_M40"),
                                new Tuple<string, string>("AI_M41","AO_M41"),
                                new Tuple<string, string>("AI_M42","AO_M42"),
                                new Tuple<string, string>("AI_M43","AO_M43"),
                                new Tuple<string, string>("AI_M44","AO_M44"),
                                new Tuple<string, string>("AI_M45","AO_M45"),

                                new Tuple<string, string>("AI_PressCtrl1","AO_PressCtrl1"),
                                new Tuple<string, string>("AI_PressCtrl2","AO_PressCtrl2"),
                                new Tuple<string, string>("AI_PressCtrl3","AO_PressCtrl3"),
                                new Tuple<string, string>("AI_PressCtrl4","AO_PressCtrl4"),
                                new Tuple<string, string>("AI_PressCtrl5","AO_PressCtrl5"),
                                new Tuple<string, string>("AI_PressCtrl6","AO_PressCtrl6"),
                                new Tuple<string, string>("AI_PressCtrl7","AO_PressCtrl7"),
                                new Tuple<string, string>("AI_PressCtrl8","AO_PressCtrl8"),
                                new Tuple<string, string>("AI_PressCtrl9","AO_PressCtrl9"),
                              
                                

                                //new Tuple<string, string>(
                                //    "AI_Gas2Flow",
                                //    "AO_Gas2Flow"
                                //),

                                //new Tuple<string, string>(
                                //    "AI_Gas3Flow",
                                //    "AO_Gas3Flow"
                                //),

                                //new Tuple<string, string>(
                                //    "AI_Gas4Flow",
                                //    "AO_Gas4Flow"
                                //),
                            };

            foreach (var item in rampList)
            {
                float setpoint = 0;
                float result = 0;
                float current = 0;
                if (IO.AI[$"{pm}.{item.Item1}"] != null)
                {
                    current = IO.AI[$"{pm}.{item.Item1}"].Value;
                    setpoint = IO.AO[$"{pm}.{item.Item2}"].Value;
                }


                if (current >= setpoint)
                {
                    result = current - 50;
                    if (result < setpoint)
                        result = setpoint;
                }
                if (current < setpoint)
                {
                    result = current + 50;
                    if (result > setpoint)
                        result = setpoint;
                }

                result = result + (float)_rnd.NextDouble();

                IO.AI[$"{pm}.{item.Item1}"].Value = result;
            }
        }
        public object locker = new object();
        private void MonitorPm(string pm)
        {
            IO.AI[$"{pm}.AI_TVmode"].Value = IO.AO[$"{pm}.AO_ValveModeSetpoint"].Value;
            IO.AI[$"{pm}.AI_HeartBeat"].Value = IO.AO[$"{pm}.AO_HeartBeat"].Value;

            IO.AI[$"{pm}.AI_ActualPositon"].Value = IO.AO[$"{pm}.AO_SetpointPositon"].Value;

            //蝶阀开启,跟着蝶阀的设置值走
            if (IO.DO[$"{pm}.DO_TVEnable"].Value)
            {
                if (IO.AI[$"{pm}.AI_ActualPressure"].Value > IO.AO[$"{pm}.AO_SetpointPressure"].Value)
                {
                    if (IO.AI[$"{pm}.AI_ActualPressure"].Value - 10 < IO.AO[$"{pm}.AO_SetpointPressure"].Value)
                    {
                        IO.AI[$"{pm}.AI_ActualPressure"].Value -= 10;
                    }
                    else
                    {
                        IO.AI[$"{pm}.AI_ActualPressure"].Value = IO.AO[$"{pm}.AO_SetpointPressure"].Value;
                    }
                }
                else if (IO.AI[$"{pm}.AI_ActualPressure"].Value < IO.AO[$"{pm}.AO_SetpointPressure"].Value)
                {
                    if (IO.AI[$"{pm}.AI_ActualPressure"].Value + 10 < IO.AO[$"{pm}.AO_SetpointPressure"].Value)
                    {
                        IO.AI[$"{pm}.AI_ActualPressure"].Value += 10;
                    }
                    else
                    {
                        IO.AI[$"{pm}.AI_ActualPressure"].Value = IO.AO[$"{pm}.AO_SetpointPressure"].Value;
                    }
                }
            }
            else
            {
                //判断是否有进气(V89到V97是否有开阀)
                if (IO.DI[$"{pm}.DI_InnerGasFinalFB(V89)"].Value || IO.DI[$"{pm}.DI_MiddleGasFinalFB(V90)"].Value || IO.DI[$"{pm}.DI_OpticPurgeFinalFB(V91)"].Value || IO.DI[$"{pm}.DI_GasRingPurgeFinalFB(V92)"].Value
                    || IO.DI[$"{pm}.DI_ChamberPurgeFinalFB(V93)"].Value || IO.DI[$"{pm}.DI_RotationUpPurgeFinalFB(V94)"].Value || IO.DI[$"{pm}.DI_ConfinementRingFinalFB(V95)"].Value || IO.DI[$"{pm}.DI_HeaterWFFinalFB(V96)"].Value)
                {
                    if (IO.AI[$"{pm}.AI_ActualPressure"].Value < 1200)
                    {
                        IO.AI[$"{pm}.AI_ActualPressure"].Value += 10;
                    }
                }
            }

            //蝶阀Ramp有Bug,设置AO值可以化解
            if (IO.AI[$"{pm}.AI_ActualPressure"].Value >= 1100)
            {
                IO.AO[$"{pm}.AO_SetpointPressure"].Value = IO.AI[$"{pm}.AI_ActualPressure"].Value;
            }

            IO.AI[$"{pm}.AI_ChamPress"].Value = IO.AI[$"{pm}.AI_ActualPressure"].Value;

            //V27自动打开
            if (IO.AI[$"{pm}.AI_ChamPress"].Value > 1020 && IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value != true)
            {
                IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value = true;
            }
            if (IO.AI[$"{pm}.AI_ChamPress"].Value < 900 && IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value)
            {
                IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value = false;
            }

            //设置PT2的压力比PT1的小20

            IO.AI[$"{pm}.AI_ForelinePress"].Value = IO.AI[$"{pm}.AI_ChamPress"].Value - 20 > 0 ? IO.AI[$"{pm}.AI_ChamPress"].Value - 20 : 0;

        }

        private void MonitorPressureLoad()
        {


            IO.DI["DI_LoadLidLocked"].Value = IO.DO["DO_LoadLidLock"].Value;
            IO.DI["DI_LoadLidUnlocked"].Value = IO.DO["DO_LoadLidUnlock"].Value;


            IO.DI["DI_LoadPressureATM"].Value = IO.AI["AI_LoadPressure"].Value > 960;
            IO.DI["DI_LoadPressureVAC"].Value = IO.AI["AI_LoadPressure"].Value < 310;

            bool isSlowPum = IO.DI["DI_LoadSlowPumpFB"].Value;
            bool isFastPump = IO.DI["DI_LoadFastPumpFB"].Value;
            bool isSlowVent = IO.DI["DI_LoadVentFB"].Value;

            //200毫秒调用一次，10秒内实现从0到1020 
            double pressure = IO.AI["AI_LoadPressure"].Value;

            if (isFastPump || isSlowPum)
            {
                if (pressure > 350)
                {
                    pressure -= 10;
                }
                else if (pressure >= 250 && pressure <= 350)
                {
                    pressure -= 4;
                }
                else
                {
                    pressure -= 10;
                }
            }
            else if (isSlowVent)
            {
                if (pressure > 320)
                {
                    pressure += 10;
                }
                else if (pressure >= 290 && pressure <= 320)
                {
                    pressure += 1;
                }
                else
                {
                    pressure += 10;
                }
            }

            if (pressure < 0)
                pressure = 0;
            if (pressure > 1020)
                pressure = 1020;

            if (!isFastPump && pressure < 1)
                pressure = 0;

            IO.AI["AI_LoadPressure"].Value = Convert.ToInt16(pressure);
        }

        private void MonitorPressureUnLoad()
        {
            IO.DI["DI_UnloadSlowPumpFB"].Value = IO.DO["DO_UnloadSlowPump"].Value;
            IO.DI["DI_UnloadFastPumpFB"].Value = IO.DO["DO_UnloadFastPump"].Value;

            bool isSlowPum = IO.DI["DI_UnloadSlowPumpFB"].Value;
            bool isFastPump = IO.DI["DI_UnloadFastPumpFB"].Value;
            bool isSlowVent = IO.DI["DI_UnloadVentFB"].Value;

            //200毫秒调用一次，10秒内实现从0到1020 
            double pressure = IO.AI["AI_UnloadPressure"].Value;

            if (isFastPump || isSlowPum)
            {
                if (pressure > 400)
                {
                    pressure -= 10;
                }
                else if (pressure >= 300 && pressure <= 400)
                {
                    pressure -= 4;
                }
                else
                {
                    pressure -= 10;
                }
            }
            else if (isSlowVent)
            {
                if (pressure > 320)
                {
                    pressure += 10;
                }
                else if (pressure >= 290 && pressure <= 320)
                {
                    pressure += 1;
                }
                else
                {
                    pressure += 10;
                }
            }

            if (pressure < 0)
                pressure = 0;
            if (pressure > 1020)
                pressure = 1020;

            if (!isFastPump && pressure < 1)
                pressure = 0;

            IO.AI["AI_UnloadPressure"].Value = Convert.ToInt16(pressure);
        }

        private void MonitorPressureTM()
        {
            IO.DI["DI_TMPressure1VAC"].Value = IO.AI["AI_TMPressure1"].Value < 500;

            bool isSlowPum = IO.DI["DI_TMSlowPumpFB"].Value;
            bool isSlowVent = IO.DI["DI_TMVentFB"].Value;
            bool isFastPump = IO.DI["DI_TMFastPumpFB"].Value;

            if (IO.DI["DI_ReactorADoorOpened"].Value || IO.DI["PM1.DI_TMPressBalanceFB(V70)"].Value)
            {
                IO.AI["AI_TMPressure1"].Value = Convert.ToInt16(IO.AI[$"PM1.AI_ChamPress"].Value);
                return;
            }
            if (IO.DI["DI_ReactorBDoorOpened"].Value || IO.DI["PM2.DI_TMPressBalanceFB(V70)"].Value)
            {
                IO.AI["AI_TMPressure1"].Value = Convert.ToInt16(IO.AI[$"PM2.AI_ChamPress"].Value);
                return;
            }
            else if (IO.DI["DI_TMLoadBanlanceFB"].Value)
            {
                IO.AI["AI_LoadPressure"].Value = IO.AI["AI_TMPressure1"].Value;
            }
            else if (IO.DI["DI_TMToUnloadBanlanceFB"].Value)
            {
                IO.AI["AI_TMPressure1"].Value = IO.AI["AI_UnloadPressure"].Value;
            }
            else
            {
                //200毫秒调用一次，10秒内实现从0到1020 
                double pressure = IO.AI["AI_TMPressure1"].Value;

                double factor = pressure / (3 * 10);

                double pressureStep = factor < 1 ? 1 : factor;

                if (isFastPump)
                {
                    pressure -= pressureStep;
                }
                else if (isSlowPum)
                {
                    pressure -= 2;
                }
                if (isSlowVent)
                {
                    if (pressure < 300)
                    {
                        pressure += 2;
                    }
                    else if (pressure < 400)
                    {
                        pressure += 10;
                    }
                    else
                    {
                        pressure += 100;
                    }
                }

                if (pressure < 0)
                    pressure = 0;
                if (pressure > 1020)
                    pressure = 1020;

                if (!isFastPump && pressure < 1)
                {
                    pressure = 0;
                }

                IO.AI["AI_TMPressure1"].Value = Convert.ToInt16(pressure);

                if (IO.AI["AI_LoadPressure"].Value > 960)
                {
                    IO.DI["DI_LoadPressureATM"].Value = true;
                }
                else
                {
                    IO.DI["DI_LoadPressureATM"].Value = false;
                }

                if (IO.AI["AI_TMPressure1"].Value > 960)
                {
                    IO.DI["DI_TMPressure1ATM"].Value = true;
                }
                else
                {
                    IO.DI["DI_TMPressure1ATM"].Value = false;
                }
            }
        }

        private void MonitorSlitValveFlow()
        {

            if (IO.DO["DO_LoadDoorClose"].Value != IO.DO["DO_LoadDoorOpen"].Value)
            {
                IO.DI["DI_LoadDoorOpened"].Value = IO.DO["DO_LoadDoorOpen"].Value;
                IO.DI["DI_LoadDoorClosed"].Value = IO.DO["DO_LoadDoorClose"].Value;
            }

            if (IO.DO["DO_RectorADoorClose"].Value != IO.DO["DO_RectorADoorOpen"].Value)
            {
                IO.DI["DI_ReactorADoorOpened"].Value = IO.DO["DO_RectorADoorOpen"].Value;
                IO.DI["DI_ReactorADoorClosed"].Value = IO.DO["DO_RectorADoorClose"].Value;
            }

            if (IO.DO["DO_RectorBDoorClose"].Value != IO.DO["DO_RectorBDoorOpen"].Value)
            {
                IO.DI["DI_ReactorBDoorOpened"].Value = IO.DO["DO_RectorBDoorOpen"].Value;
                IO.DI["DI_ReactorBDoorClosed"].Value = IO.DO["DO_RectorBDoorClose"].Value;
            }

            if (IO.DO["DO_BufferStationDoorOpen"].Value != IO.DO["DO_BufferStationDoorClose"].Value)
            {
                IO.DI["DI_BufferStationDoorOpened"].Value = IO.DO["DO_BufferStationDoorOpen"].Value;
                IO.DI["DI_BufferStationDoorClosed"].Value = IO.DO["DO_BufferStationDoorClose"].Value;
            }

            if (IO.DO["DO_UnloadSubStationDoorOpen"].Value != IO.DO["DO_UnloadSubStationDoorClose"].Value)
            {
                IO.DI["DI_UnloadSubStationDoorOpened"].Value = IO.DO["DO_UnloadSubStationDoorOpen"].Value;
                IO.DI["DI_UnloadSubStationDoorClosed"].Value = IO.DO["DO_UnloadSubStationDoorClose"].Value;
            }

            if (IO.DO["DO_LoadLSideDoorOpen"].Value != IO.DO["DO_LoadLSideDoorClose"].Value)
            {
                IO.DI["DI_LoadLSideDoorOpened"].Value = IO.DO["DO_LoadLSideDoorOpen"].Value;
                IO.DI["DI_LoadLSideDoorClosed"].Value = IO.DO["DO_LoadLSideDoorClose"].Value;
            }

            if (IO.DO["DO_LoadRSideDoorOpen"].Value != IO.DO["DO_LoadRSideDoorClose"].Value)
            {
                IO.DI["DI_LoadRSideDoorOpened"].Value = IO.DO["DO_LoadRSideDoorOpen"].Value;
                IO.DI["DI_LoadRSideDoorClosed"].Value = IO.DO["DO_LoadRSideDoorClose"].Value;
            }
        }


        private int time1 = 0;
        private int time2 = 0;
        private int time3 = 0;
        private int time4 = 0;
        private int time5 = 0;

        private void MonitorTMValve()
        {

            //DI_LoadLidClose
            IO.DI["DI_LoadLidClose"].Value = IO.DO["DO_LoadLidClose"].Value;
            IO.DI["DI_LoadLidOpen"].Value = IO.DO["DO_LoadLidOpen"].Value;
            IO.DI["DI_VacRobotExtendBufferEnableFB"].Value = IO.DO["DO_VacRobotExtendBufferEnable"].Value;
            IO.DI["DI_VacRobotExtenLoadEnableFB"].Value = IO.DO["DO_VacRobotExtenLoadEnable"].Value;
            IO.DI["DI_VacRobotExtendPMAEnableFB"].Value = IO.DO["DO_VacRobotExtendPMAEnable"].Value;
            IO.DI["DI_VacRobotExtendPMBEnableFB"].Value = IO.DO["DO_VacRobotExtendPMBEnable"].Value;
            IO.DI["DI_VacRobotExtendUnloadEnableFB"].Value = IO.DO["DO_VacRobotExtendUnloadEnable"].Value;


            IO.DI["DI_ATMRobotExtendUnloadEnableFB"].Value = IO.DO["DO_ATMRobotExtendUnloadEnable"].Value;
            IO.DI["DI_ATMRobotExtendLoadLSideEnableFB"].Value = IO.DO["DO_ATMRobotExtendLoaLSideEnable"].Value;
            IO.DI["DI_ATMRobotExtendLoadRSideEnableFB"].Value = IO.DO["DO_ATMRobotExtendLoaRSideEnable"].Value;


            IO.DI["DI_LoadSlowPumpFB"].Value = IO.DO["DO_LoadSlowPump"].Value;
            IO.DI["DI_LoadFastPumpFB"].Value = IO.DO["DO_LoadFastPump"].Value;
            IO.DI["DI_TMSlowPumpFB"].Value = IO.DO["DO_TMSlowPump"].Value;
            IO.DI["DI_TMFastPumpFB"].Value = IO.DO["DO_TMFastPump"].Value;
            IO.DI["DI_BufferVentFB"].Value = IO.DO["DO_BufferVent"].Value;
            IO.DI["DI_LoadVentFB"].Value = IO.DO["DO_LoadVent"].Value;
            IO.DI["DI_TMVentFB"].Value = IO.DO["DO_TMVent"].Value;
            IO.DI["DI_UnloadVentFB"].Value = IO.DO["DO_UnloadVent"].Value;
            IO.DI["DI_TMLoadBanlanceFB"].Value = IO.DO["DO_TMLoadBanlance"].Value;


            IO.DI["DI_VacRobotExtenLoadEnableFB"].Value = IO.DO["DO_VacRobotExtenLoadEnable"].Value;
            IO.DI["DI_VacRobotExtendBufferEnableFB"].Value = IO.DO["DO_VacRobotExtendBufferEnable"].Value;
            IO.DI["DI_VacRobotExtendPMAEnableFB"].Value = IO.DO["DO_VacRobotExtendPMAEnable"].Value;


            if (IO.DO["DO_LoadLidLock"].Value != IO.DO["DO_LoadLidUnlock"].Value)
            {
                time1++;
                if (time1 > 10)
                {
                    time1 = 0;
                    IO.DI["DI_LoadLidLocked"].Value = IO.DO["DO_LoadLidLock"].Value;
                    IO.DI["DI_LoadLidUnlocked"].Value = IO.DO["DO_LoadLidUnlock"].Value;
                }
            }
            if (IO.DO["DO_LoadWaferCYClamp"].Value != IO.DO["DO_LoadWaferCYOpen"].Value)
            {
                time2++;
                if (time2 > 10)
                {
                    time2 = 0;
                    IO.DI["DI_LoadWaferCYClamped"].Value = IO.DO["DO_LoadWaferCYClamp"].Value;
                    IO.DI["DI_LoadWafeCYOpened"].Value = IO.DO["DO_LoadWaferCYOpen"].Value;
                }
            }
            if (IO.DO["DO_LoadTrayCYClamp"].Value != IO.DO["DO_LoadTrayCYOpen"].Value)
            {
                time3++;
                if (time3 > 10)
                {
                    time3 = 0;
                    IO.DI["DI_LoadTrayCYClamped"].Value = IO.DO["DO_LoadTrayCYClamp"].Value;
                    IO.DI["DI_LoadTrayCYOpend"].Value = IO.DO["DO_LoadTrayCYOpen"].Value;
                }
            }
            if (IO.DO["DO_UnloadStationWaferCYClamp"].Value != IO.DO["DO_UnloadStationWaferCYOpen"].Value)
            {
                time4++;
                if (time4 > 10)
                {
                    time4 = 0;
                    IO.DI["DI_UnloadStationWaferCYClamped"].Value = IO.DO["DO_UnloadStationWaferCYClamp"].Value;
                    IO.DI["DI_UnloadStationWaferCYOpened"].Value = IO.DO["DO_UnloadStationWaferCYOpen"].Value;
                }
            }
            if (IO.DO["DO_UnloadStationLifterCYUp"].Value != IO.DO["DO_UnloadStationLifterCYDown"].Value)
            {
                time5++;
                if (time5 > 10)
                {
                    time5 = 0;
                    IO.DI["DI_UnloadStationLifterCYUp"].Value = IO.DO["DO_UnloadStationLifterCYUp"].Value;
                    IO.DI["DI_UnloadStationLifterCYDown"].Value = IO.DO["DO_UnloadStationLifterCYDown"].Value;
                }
            }

            //IO.DI["DI_LdRotationServoOn"].Value = IO.DO["DO_LdRotationServoOn"].Value;

        }

        private void MonitorValve(string pm)
        {

            IO.DI[$"{pm}.DI_DORPressATMSW"].Value = IO.DI[$"{pm}.DI_DORRefillFB(V76)"].Value;
            IO.DI[$"{pm}.DI_PSUEnableFB"].Value = IO.DO[$"{pm}.DO_HeaterEnable"].Value;

            IO.DI[$"{pm}.DI_InnerHeaterEnableFB"].Value = IO.DO[$"{pm}.DO_PSU1Enable"].Value;
            IO.DI[$"{pm}.DI_MiddleHeaterEnableFB"].Value = IO.DO[$"{pm}.DO_PSU2Enable"].Value;
            IO.DI[$"{pm}.DI_OuterHeaterEnableFB"].Value = IO.DO[$"{pm}.DO_PSU3Enable"].Value;

            //IO.DI[$"{pm}.DI_SCR1Status"].Value = IO.DO[$"{pm}.DO_SCR1Enable"].Value;
            //IO.DI[$"{pm}.DI_SCR2Status"].Value = IO.DO[$"{pm}.DO_SCR2Enable"].Value;
            //IO.DI[$"{pm}.DI_SCR3Status"].Value = IO.DO[$"{pm}.DO_SCR3Enable"].Value;

            

            IO.DI[$"{pm}.DI_ChamMoveBodyUpDownEnableFB"].Value = IO.DO[$"{pm}.DO_ChamMoveBodyUpDownEnable"].Value;

            IO.DI[$"{pm}.DI_ArSafetyBypassFB(V19)"].Value = IO.DO[$"{pm}.DO_ArSafetyBypass(V19)"].Value;
            IO.DI[$"{pm}.DI_H2SupplyFB(V30)"].Value = IO.DO[$"{pm}.DO_H2Supply(V30)"].Value;
            IO.DI[$"{pm}.DI_PumpBypassFB(V27)"].Value = IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value;
            IO.DI[$"{pm}.DI_H2SupplyFB(V31)"].Value = IO.DO[$"{pm}.DO_H2Supply(V31)"].Value;
            IO.DI[$"{pm}.DI_ArSupplyFB(V32)"].Value = IO.DO[$"{pm}.DO_ArSupply(V32)"].Value;
            IO.DI[$"{pm}.DI_SHH2/ArSwitchFB(V33)"].Value = IO.DO[$"{pm}.DO_SHH2/ArSwitch(V33)"].Value;
            IO.DI[$"{pm}.DI_H2ArLine1FB(V35)"].Value = IO.DO[$"{pm}.DO_H2ArLine1(V35)"].Value;
            IO.DI[$"{pm}.DI_H2ArLine2FB(V36)"].Value = IO.DO[$"{pm}.DO_H2ArLine2(V36)"].Value;
            //IO.DI[$"{pm}.DI_DoppingDilute_FB"].Value = IO.DO[$"{pm}.DO_HighN2Flow"].Value;
            IO.DI[$"{pm}.DI_H2ArLine2FB(V36)"].Value = IO.DO[$"{pm}.DO_H2ArLine2(V36)"].Value;
            IO.DI[$"{pm}.DI_N2SourceFB(V38)"].Value = IO.DO[$"{pm}.DO_N2Source(V38)"].Value;
            IO.DI[$"{pm}.DI_TMASourceFB(V100)"].Value = IO.DO[$"{pm}.DO_TMASource(V100)"].Value;

            IO.DI[$"{pm}.DI_HighN2Run/VentFB(V40)"].Value = IO.DO[$"{pm}.DO_HighN2Run/Vent(V40)"].Value;
            IO.DI[$"{pm}.DI_TMARunFB(V41)"].Value = IO.DO[$"{pm}.DO_TMARun(V41)"].Value;
            IO.DI[$"{pm}.DI_TMAVentFB(V42)"].Value = IO.DO[$"{pm}.DO_TMAVent(V42)"].Value;
            IO.DI[$"{pm}.DI_TMAReleaseFB(V43)"].Value = IO.DO[$"{pm}.DO_TMARelease(V43)"].Value;
            IO.DI[$"{pm}.DI_TMABypassFB(V45)"].Value = IO.DO[$"{pm}.DO_TMABypass(V45)"].Value;
            IO.DI[$"{pm}.DI_TMAVacFB(V46)"].Value = IO.DO[$"{pm}.DO_TMAVac(V46)"].Value;
            IO.DI[$"{pm}.DI_TCSReleaseFB(V48)"].Value = IO.DO[$"{pm}.DO_TCSRelease(V48)"].Value;
            IO.DI[$"{pm}.DI_TCSBypassFB(V49)"].Value = IO.DO[$"{pm}.DO_TCSBypass(V49)"].Value;
            IO.DI[$"{pm}.DI_TCSVacFB(V50)"].Value = IO.DO[$"{pm}.DO_TCSVac(V50)"].Value;
            IO.DI[$"{pm}.DI_HCLSwitchFB(V51)"].Value = IO.DO[$"{pm}.DO_HCLSwitch(V51)"].Value;
            IO.DI[$"{pm}.DI_SiH4SwitchFB(V52)"].Value = IO.DO[$"{pm}.DO_SiH4Switch(V52)"].Value;
            IO.DI[$"{pm}.DI_TCSRun/VentFB(V53)"].Value = IO.DO[$"{pm}.DO_TCSRun/Vent(V53)"].Value;
            IO.DI[$"{pm}.DI_HCLRun/VentFB(V54)"].Value = IO.DO[$"{pm}.DO_HCLRun/Vent(V54)"].Value;
            IO.DI[$"{pm}.DI_SiH4RunFB(V55)"].Value = IO.DO[$"{pm}.DO_SiH4Run(V55)"].Value;
            IO.DI[$"{pm}.DI_SiH4VentFB(V56)"].Value = IO.DO[$"{pm}.DO_SiH4Vent(V56)"].Value;
            IO.DI[$"{pm}.DI_DoppingN2Final(V57)"].Value = IO.DO[$"{pm}.DO_DoppingN2Final(V57)"].Value;
            IO.DI[$"{pm}.DI_C2H4SwitchFB(V58)"].Value = IO.DO[$"{pm}.DO_C2H4Switch(V58)"].Value;
            IO.DI[$"{pm}.DI_C2H4RunFB(V59)"].Value = IO.DO[$"{pm}.DO_C2H4Run(V59)"].Value;
            IO.DI[$"{pm}.DI_C2H4VentFB(V60)"].Value = IO.DO[$"{pm}.DO_C2H4Vent(V60)"].Value;
            IO.DI[$"{pm}.DI_DoppingFinalFB(V61)"].Value = IO.DO[$"{pm}.DO_DoppingFinal(V61)"].Value;
            IO.DI[$"{pm}.DI_SilaneFinalFB(V62)"].Value = IO.DO[$"{pm}.DO_SilaneFinal(V62)"].Value;
            IO.DI[$"{pm}.DI_PropaneFinalFB(V63)"].Value = IO.DO[$"{pm}.DO_PropaneFinal(V63)"].Value;
            IO.DI[$"{pm}.DI_CarrierGasH2FB(V64)"].Value = IO.DO[$"{pm}.DO_CarrierGasH2(V64)"].Value;
            IO.DI[$"{pm}.DI_CarrierGasArFB(V65)"].Value = IO.DO[$"{pm}.DO_CarrierGasAr(V65)"].Value;

			//IO.DI[$"{pm}.DI_GasRingH2Purge_FB"].Value = IO.DO[$"{pm}.DO_GasRingH2Purge"].Value;
			//IO.DI[$"{pm}.DI_GasRingArPurge_FB"].Value = IO.DO[$"{pm}.DO_GasRingArPurge"].Value;
			IO.DI[$"{pm}.DI_ChamBodyArPurgeFB(V68)"].Value = IO.DO[$"{pm}.DO_ChamBodyArPurge(V68)"].Value;
            IO.DI[$"{pm}.DI_ReactorLeakCheckFB(V69)"].Value = IO.DO[$"{pm}.DO_ReactorLeakCheck(V69)"].Value;
            IO.DI[$"{pm}.DI_TMPressBalanceFB(V70)"].Value = IO.DO[$"{pm}.DO_TMPressBalance(V70)"].Value;
            IO.DI[$"{pm}.DI_CarryGasFinalFB(V97)"].Value = IO.DO[$"{pm}.DO_CarryGasFinal(V97)"].Value;
            IO.DI[$"{pm}.DI_GasBoxVentPumpFB(V72)"].Value = IO.DO[$"{pm}.DO_GasBoxVentPump(V72)"].Value;
            IO.DI[$"{pm}.DI_MOVacFB(V73)"].Value = IO.DO[$"{pm}.DO_MOVac(V73)"].Value;
            IO.DI[$"{pm}.DI_GasboxLeakCheckFB(V74)"].Value = IO.DO[$"{pm}.DO_GasboxLeakCheck(V74)"].Value;
            IO.DI[$"{pm}.DI_DORVacFB(V75)"].Value = IO.DO[$"{pm}.DO_DORVac(V75)"].Value;
            IO.DI[$"{pm}.DI_DORRefillFB(V76)"].Value = IO.DO[$"{pm}.DO_DORRefill(V76)"].Value;
            IO.DI[$"{pm}.DI_SHPurgeFinalFB(V87)"].Value = IO.DO[$"{pm}.DO_SHPurgeFinal(V87)"].Value;
            IO.DI[$"{pm}.DI_OuterGasFinalFB(V88)"].Value = IO.DO[$"{pm}.DO_OuterGasFinal(V88)"].Value;
            IO.DI[$"{pm}.DI_InnerGasFinalFB(V89)"].Value = IO.DO[$"{pm}.DO_InnerGasFinal(V89)"].Value;
            IO.DI[$"{pm}.DI_MiddleGasFinalFB(V90)"].Value = IO.DO[$"{pm}.DO_MiddleGasFinal(V90)"].Value;
            IO.DI[$"{pm}.DI_OpticPurgeFinalFB(V91)"].Value = IO.DO[$"{pm}.DO_GasRingPurgeFinal(V92)"].Value;
            IO.DI[$"{pm}.DI_GasRingPurgeFinalFB(V92)"].Value = IO.DO[$"{pm}.DO_OpticPurgeFinal(V91)"].Value;
            IO.DI[$"{pm}.DI_ChamberPurgeFinalFB(V93)"].Value = IO.DO[$"{pm}.DO_ChamberPurgeFinal(V93)"].Value;
            IO.DI[$"{pm}.DI_RotationUpPurgeFinalFB(V94)"].Value = IO.DO[$"{pm}.DO_RotationUpPurgeFinal(V94)"].Value;
            IO.DI[$"{pm}.DI_ConfinementRingFinalFB(V95)"].Value = IO.DO[$"{pm}.DO_ConfinementRingFinal(V95)"].Value;
            IO.DI[$"{pm}.DI_HeaterWFFinalFB(V96)"].Value = IO.DO[$"{pm}.DO_HeaterWFFinal(V96)"].Value;
            IO.DI[$"{pm}.DI_HeaterWFFinalFB(V96)"].Value = IO.DO[$"{pm}.DO_HeaterWFFinal(V96)"].Value;
            IO.DI[$"{pm}.DI_N2SwitchFB(V37)"].Value = IO.DO[$"{pm}.DO_N2Switch(V37)"].Value;
            IO.DI[$"{pm}.DI_TMASourceFB(V100)"].Value = IO.DO[$"{pm}.DO_TMASource(V100)"].Value;

            IO.DI[$"{pm}.DI_NdopeDiluteVentFB(V103)"].Value = IO.DO[$"{pm}.DO_NdopeDiluteVent(V103)"].Value;
            IO.DI[$"{pm}.DI_PdopeDiluteVentFB(V105)"].Value = IO.DO[$"{pm}.DO_PdopeDiluteVent(V105)"].Value;
            //diOpen = "DI_PN2Run/VentFB(V47)" doOpen = "DO_PN2Run/Vent(V47)"
            //IO.DI[$"{pm}.DI_CarrierGasH2_FB"].Value = IO.DO[$"{pm}.DO_CarrierGasH2"].Value;
            //IO.DI[$"{pm}.DI_CarrierGasAr_FB"].Value = IO.DO[$"{pm}.DO_CarrierGasAr"].Value;



            IO.DI[$"{pm}.DI_OpticPurgeFinalFB(V91)"].Value = IO.DO[$"{pm}.DO_OpticPurgeFinal(V91)"].Value;
            IO.DI[$"{pm}.DI_GasRingPurgeFinalFB(V92)"].Value = IO.DO[$"{pm}.DO_GasRingPurgeFinal(V92)"].Value;

            //IO.DI[$"{pm}.DI_GasBoxVentBypass"].Value = IO.DO[$"{pm}.DO_GasBoxVentBypass(V25)"].Value;
            //IO.DI[$"{pm}.DI_C2H4SwitchHTPurge"].Value = IO.DO[$"{pm}.DO_C2H4SwitchHTPurge"].Value;

            IO.DI[$"{pm}.DI_EPV1-1FB"].Value = IO.DO[$"{pm}.DO_EPV1"].Value;
            IO.DI[$"{pm}.DI_EPV2-1FB"].Value = IO.DO[$"{pm}.DO_EPV2"].Value;

            IO.AI[$"{pm}.AI_PressCtrl1"].Value = IO.AO[$"{pm}.AO_PressCtrl1"].Value;
            IO.AI[$"{pm}.AI_PressCtrl2"].Value = IO.AO[$"{pm}.AO_PressCtrl2"].Value;
            IO.AI[$"{pm}.AI_PressCtrl3"].Value = IO.AO[$"{pm}.AO_PressCtrl3"].Value;
            IO.AI[$"{pm}.AI_PressCtrl4"].Value = IO.AO[$"{pm}.AO_PressCtrl4"].Value;
            IO.AI[$"{pm}.AI_PressCtrl5"].Value = IO.AO[$"{pm}.AO_PressCtrl5"].Value;
            IO.AI[$"{pm}.AI_PressCtrl6"].Value = IO.AO[$"{pm}.AO_PressCtrl6"].Value;
            IO.AI[$"{pm}.AI_PressCtrl7"].Value = IO.AO[$"{pm}.AO_PressCtrl7"].Value;
            IO.AI[$"{pm}.AI_PressCtrl8"].Value = IO.AO[$"{pm}.AO_PressCtrl8"].Value;
        }

        int timeMoveUp = 0;
        int timeMove = 0;
        R_TRIG _UpTrig = new R_TRIG();

        private void MonitorChamberMoveBodyUp(string pm)
        {
            if (IO.DO[$"{pm}.DO_ChamMoveBodyUp"].Value != IO.DO[$"{pm}.DO_ChamMoveBodyDown"].Value)
            {
                timeMoveUp++;
                if (timeMoveUp > 20)
                {
                    IO.DI[$"{pm}.DI_ChamMoveBodyUp"].Value = IO.DO[$"{pm}.DO_ChamMoveBodyUp"].Value;
                    IO.DI[$"{pm}.DI_ChamMoveBodyDown"].Value = IO.DO[$"{pm}.DO_ChamMoveBodyDown"].Value;
                }
            }
            if (timeMoveUp > 20)
            {
                timeMoveUp = 0;
            }
        }

        R_TRIG forwardLatch_R = new R_TRIG();
        R_TRIG backLatchLatch_R = new R_TRIG();
        private void MonitorChamberMoveBody(string pm)
        {
            if (IO.DO[$"{pm}.DO_ChamMoveBodyForward"].Value != IO.DO[$"{pm}.DO_ChamMoveBodyBackward"].Value)
            {
                timeMove++;
                if (timeMove > 20)
                {
                    IO.DI[$"{pm}.DI_ChamMoveBodyFront"].Value = IO.DO[$"{pm}.DO_ChamMoveBodyForward"].Value;
                    IO.DI[$"{pm}.DI_ChamMoveBodyEnd"].Value = IO.DO[$"{pm}.DO_ChamMoveBodyBackward"].Value;
                }
            }

            forwardLatch_R.CLK = IO.DO[$"{pm}.DO_ChamMoveBodyBrakerForward"].Value;
            if (forwardLatch_R.Q)
            {
                IO.DI[$"{pm}.DI_ChamMoveBodyUpLatchFW"].Value = true;
                IO.DI[$"{pm}.DI_ChamMoveBodyEndLatchBW"].Value = false;
                backLatchLatch_R.RST = true;
            }

            backLatchLatch_R.CLK = IO.DO[$"{pm}.DO_ChamMoveBodyBrakerBackward"].Value;
            if (backLatchLatch_R.Q)
            {
                IO.DI[$"{pm}.DI_ChamMoveBodyEndLatchBW"].Value = true;
                IO.DI[$"{pm}.DI_ChamMoveBodyUpLatchFW"].Value = false;
                forwardLatch_R.RST = true;
            }

            if (timeMove > 20)
            {
                timeMove = 0;
            }
        }

        private void MonitorHeater(string pm)
        {
            IO.DI[$"{pm}.DI_PSU1Status"].Value = IO.DO[$"{pm}.DO_PSU1Enable"].Value;
            IO.DI[$"{pm}.DI_PSU2Status"].Value = IO.DO[$"{pm}.DO_PSU2Enable"].Value;
            IO.DI[$"{pm}.DI_PSU3Status"].Value = IO.DO[$"{pm}.DO_PSU3Enable"].Value;
            IO.DI[$"{pm}.DI_SCR1Status"].Value = IO.DO[$"{pm}.DO_SCR1Enable"].Value;
            IO.DI[$"{pm}.DI_SCR2Status"].Value = IO.DO[$"{pm}.DO_SCR2Enable"].Value;
            IO.DI[$"{pm}.DI_SCR3Status"].Value = IO.DO[$"{pm}.DO_SCR3Enable"].Value;

            //IO.AI[$"{pm}.AI_PresentLoop1Temp"].Value = IO.AO[$"{pm}.AO_SetpointLoop1Temp"].Value;
            //IO.AI[$"{pm}.AI_Loop1ControlMode"].Value = IO.AO[$"{pm}.AO_Loop1ControlMode"].Value;
            //IO.AI[$"{pm}.AI_Loop1ActualPower"].Value = IO.AO[$"{pm}.AO_Loop1ManualOP"].Value;
            //IO.DI[$"{pm}.DI_InnerHeaterEnable"].Value = IO.DO[$"{pm}.DO_InnerHeaterEnable"].Value;

            //IO.AI[$"{pm}.AI_PresentLoop2Temp"].Value = IO.AO[$"{pm}.AO_SetpointLoop2Temp"].Value;
            //IO.AI[$"{pm}.AI_Loop2ControlMode"].Value = IO.AO[$"{pm}.AO_Loop2ControlMode"].Value;
            //IO.AI[$"{pm}.AI_Loop2ActualPower"].Value = IO.AO[$"{pm}.AO_Loop2ManualOP"].Value;
            //IO.DI[$"{pm}.DI_MiddleHeaterEnable"].Value = IO.DO[$"{pm}.DO_MiddleHeaterEnable"].Value;

            //IO.AI[$"{pm}.AI_PresentLoop3Temp"].Value = IO.AO[$"{pm}.AO_SetpointLoop3Temp"].Value;
            //IO.AI[$"{pm}.AI_Loop3ControlMode"].Value = IO.AO[$"{pm}.AO_Loop3ControlMode"].Value;
            //IO.AI[$"{pm}.AI_Loop3ActualPower"].Value = IO.AO[$"{pm}.AO_Loop3ManualOP"].Value;
            //IO.DI[$"{pm}.DI_OuterHeaterEnable"].Value = IO.DO[$"{pm}.DO_OuterHeaterEnable"].Value;
        }
        private void MonitorGasConnector(string pm)
        {
            if (IO.DO[$"{pm}.DO_SHGasConnectorLoosen"].Value != IO.DO[$"{pm}.DO_SHGasConnectorTighten"].Value)
            {
                IO.DI[$"{pm}.DI_SHGasConnectorLoosen"].Value = IO.DO[$"{pm}.DO_SHGasConnectorLoosen"].Value;
                IO.DI[$"{pm}.DI_SHGasConnectorTighten"].Value = IO.DO[$"{pm}.DO_SHGasConnectorTighten"].Value;
            }
        }

        private void MonitorLid(string pm)
        {

            if (IO.DO[$"{pm}.DO_SHLidLoosen"].Value != IO.DO[$"{pm}.DO_SHLidTighten"].Value)
            {
                timeMove++;
                if (timeMove > 20)
                {
                    IO.DI[$"{pm}.DI_SHLidLoosen"].Value = IO.DO[$"{pm}.DO_SHLidLoosen"].Value;
                    IO.DI[$"{pm}.DI_SHLidTighten"].Value = IO.DO[$"{pm}.DO_SHLidTighten"].Value;
                    IO.DI[$"{pm}.DI_SHLidClosed"].Value = IO.DO[$"{pm}.DO_SHLidTighten"].Value;
                }
                return;
            }
            if (IO.DO[$"{pm}.DO_MiddleLidLoosen"].Value != IO.DO[$"{pm}.DO_MiddleLidTighten"].Value)
            {
                timeMove++;
                if (timeMove > 20)
                {
                    IO.DI[$"{pm}.DI_MiddleLidLoosen"].Value = IO.DO[$"{pm}.DO_MiddleLidLoosen"].Value;
                    IO.DI[$"{pm}.DI_MiddleLidTighten"].Value = IO.DO[$"{pm}.DO_MiddleLidTighten"].Value;
                    IO.DI[$"{pm}.DI_MiddleLidClosed"].Value = IO.DO[$"{pm}.DO_MiddleLidTighten"].Value;
                }
                return;
            }
            if (timeMove > 20)
            {
                timeMove = 0;
            }
        }

        private void MonitorLidSwing(string pm)
        {

            if (IO.DO[$"{pm}.DO_SHLidSwingLock"].Value != IO.DO[$"{pm}.DO_SHLidSwingUnlock"].Value)
            {
                IO.DI[$"{pm}.DI_SHLidSwingLock"].Value = IO.DO[$"{pm}.DO_SHLidSwingLock"].Value;
                IO.DI[$"{pm}.DI_SHLidSwingUnlock"].Value = IO.DO[$"{pm}.DO_SHLidSwingUnlock"].Value;
            }
            if (IO.DO[$"{pm}.DO_MiddleLidSwingLock"].Value != IO.DO[$"{pm}.DO_MiddleLidSwingUnlock"].Value)
            {
                IO.DI[$"{pm}.DI_MiddleLidSwingLock"].Value = IO.DO[$"{pm}.DO_MiddleLidSwingLock"].Value;
                IO.DI[$"{pm}.DI_MiddleLidSwingUnlock"].Value = IO.DO[$"{pm}.DO_MiddleLidSwingUnlock"].Value;
            }

        }


        private void MonitorConfinementRing(string pm)
        {
            if (IO.DO[$"{pm}.DO_ConfinementRingMoveDown"].Value != IO.DO[$"{pm}.DO_ConfinementRingMoveUp"].Value)
            {
                IO.DI[$"{pm}.DI_ConfinementRingDone"].Value = true;
                IO.DI[$"{pm}.DI_ConfinementRingDown"].Value = IO.DO[$"{pm}.DO_ConfinementRingMoveDown"].Value;
                IO.DI[$"{pm}.DI_ConfinementRingUp"].Value = IO.DO[$"{pm}.DO_ConfinementRingMoveUp"].Value;
            }

            if (IO.DI[$"{pm}.DI_ConfinementRingUp"].Value)
            {
                IO.AI[$"{pm}.AI_ConfinementRingCurPos"].Value = IO.AO[$"{pm}.AO_ConfinementRingUpPos"].Value;
            }

            if (IO.DI[$"{pm}.DI_ConfinementRingDown"].Value)
            {
                IO.AI[$"{pm}.AI_ConfinementRingCurPos"].Value = IO.AO[$"{pm}.AO_ConfinementRingDownPos"].Value;
            }

            IO.AI[$"{pm}.AI_ConfinementRingUpPos"].Value = IO.AO[$"{pm}.AO_ConfinementRingUpPos"].Value;
            IO.AI[$"{pm}.AI_ConfinementRingDownPos"].Value = IO.AO[$"{pm}.AO_ConfinementRingDownPos"].Value;
        }



        private void MonitorRotation(string pm)
        {
            IO.AI[$"{pm}.AI_ActualSpeed"].Value = IO.AO[$"{pm}.AO_SpindleSpeed"].Value;

            IO.DI[$"{pm}.DI_ConfinementRingServoOn"].Value = IO.DO[$"{pm}.DO_ConfinementRingServoOn"].Value;

        }

        public void Terminate()
        {
            _thread.Stop();
        }
    }
}
