Browse Source

check in HV, PendulumValve, TurboPump drivers.

sangwq 2 years ago
parent
commit
c8cfb4008d

+ 5 - 0
Venus/Framework/Common/Device/Bases/PumpBase.cs

@@ -83,4 +83,9 @@ namespace MECF.Framework.Common.Device.Bases
         public virtual void Reset() { }
 
     }
+
+    public abstract class TurboPump : PumpBase
+    {
+
+    }
 }

+ 270 - 0
Venus/Venus_RT/Devices/AdixenTurboPump.cs

@@ -0,0 +1,270 @@
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using MECF.Framework.Common.Communications;
+using MECF.Framework.Common.Equipment;
+
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.RT.Event;
+using Aitex.Core.RT.Device;
+
+using MECF.Framework.Common.Device.Bases;
+namespace Venus_RT.Devices
+{
+    class AdixenTurboPump : TurboPump
+    {
+        public enum Operation
+        {
+            SetAddress,
+            GetChecksum,
+            GetFaultList,
+            SetDatalogInterval,
+            EnableDatalog,
+            EnableEcho,
+            DisableEcho,
+            IdentifyDevice,
+            IdentifyProduct,
+            GetCurrentValues,
+            SwitchSpeedToNormal,
+            SwitchSpeedToStandbyValue,
+            SetStandbySpeed,
+            GetParametersState,
+            GetIntervalParametersState,
+            SetPumpWorkingTime,
+            SetElectronicWorkingTime,
+            SetStartDelay,
+            SetTimeToVent,
+            SetVentingTime,
+            SetSpeedThreshold,
+            SetControlTemperatrue,
+            StopPumpThermostage,
+            SetBearingThreshold,
+            GetCurrentSpeed,
+            StartPumpRotation,
+            StopPump,
+            SetVersions,
+            SetAnalogOutput,
+            SetTemperatureUnit,
+            SetBuzzerOpt,
+            SetCommandMode,
+            SetBraking,
+            Invalid,
+        }
+
+        private readonly Dictionary<Operation, string> _noneParaCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.EnableDatalog,               "#{0:D3}DLR\r" },
+            {Operation.EnableEcho,                  "#{0:D3}ECHON\r" },
+            {Operation.DisableEcho,                 "#{0:D3}ECHOFF\r" },
+            {Operation.SwitchSpeedToNormal,         "#{0:D3}NSP\r" },
+            {Operation.SwitchSpeedToStandbyValue,   "#{0:D3}SBY\r" },
+            {Operation.StopPumpThermostage,         "#{0:D3}SET31,30\r" },
+            {Operation.StartPumpRotation,           "#{0:D3}TMPON\r" },
+            {Operation.StopPump,                    "#{0:D3}TMPOFF\r" },
+        };
+
+        private readonly Dictionary<Operation, string> _readDataCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.GetChecksum,                 "#{0:D3}CHKVS\r" },
+            {Operation.GetFaultList,                "#{0:D3}DEF\r" },
+            {Operation.IdentifyDevice,              "#{0:D3}IDN\r" },
+            {Operation.IdentifyProduct,             "#{0:D3}IDP\r" },
+            {Operation.GetCurrentValues,            "#{0:D3}LEV10\r" },
+            {Operation.GetParametersState,          "#{0:D3}SEL10\r" },
+            {Operation.GetCurrentSpeed,             "#{0:D3}SPD\r" },
+            {Operation.GetIntervalParametersState,  "#{0:D3}STA\r" },
+        };
+
+        private readonly Dictionary<Operation, string> _setDataCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.SetAddress,                  "#{0:D3}ADR {1:D3}\r" },
+            {Operation.SetDatalogInterval,          "#{0:D3}DLI {1:D3}\r" },
+            {Operation.SetStandbySpeed,             "#{0:D3}RPM,{1:D4}\r" },
+            {Operation.SetPumpWorkingTime,          "#{0:D3}SET10,{1:D5}\r"  },
+            {Operation.SetElectronicWorkingTime,    "#{0:D3}SET11,{1:D5}\r"  },
+            {Operation.SetStartDelay,               "#{0:D3}SET13,{1:D5}\r" },
+            {Operation.SetTimeToVent,               "#{0:D3}SET14,{1:D5}\r" },
+            {Operation.SetVentingTime,              "#{0:D3}SET15,{1:D4}\r" },
+            {Operation.SetSpeedThreshold,           "#{0:D3}SET30,{1:D2}\r" },
+            {Operation.SetControlTemperatrue,       "#{0:D3}SET31,{1:D2}\r" },
+            {Operation.SetBearingThreshold,         "#{0:D3}SET32,{1:D3}\r" },
+
+            {Operation.SetAnalogOutput,             "#{0:D3}OPT01,{1:D1}\r" },
+            {Operation.SetTemperatureUnit,          "#{0:D3}OPT02,{1:D1}\r" },
+            {Operation.SetBuzzerOpt,                "#{0:D3}OPT11,{1:D1}\r" },
+            {Operation.SetCommandMode,              "#{0:D3}OPT14,{1:D1}\r" },
+            {Operation.SetBraking,                  "#{0:D3}OPT25,{1:D1}\r" },
+        };
+
+        private readonly Dictionary<string, string> _comError = new Dictionary<string, string>
+        {
+            {"Err0",  "adjustment error(out of bounds)" },
+            {"Err1",  "command error (syntax) " },
+            {"Err2",  "parameter error (e.g. non hexadecimal character)" },
+            {"Err3",  "context error" },
+            {"Err4",  "checksum error" },
+        };
+
+        private readonly int _readInterval = 500;
+        private readonly int _readTimeout = 2000;
+        private readonly int _address = 0;
+        private readonly AsyncSerialPort _serial;
+        private Stopwatch _queryWatch = new Stopwatch();
+
+        private Operation _lastReadCommand = Operation.Invalid;
+        private string _lastAlarmString = string.Empty;
+
+        private Regex _rex_ok = new Regex(@"#\d{1,3},OK");
+        private Regex _rex_err = new Regex(@"#\d{1,3},Err");
+
+        public AdixenTurboPump(ModuleName mod)
+        {
+            Module = mod.ToString();
+            var _PortNum = SC.GetStringValue($"{mod}.TurboPump.Port");
+            _serial = new AsyncSerialPort(_PortNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One);
+        }
+
+        public override bool Initialize()
+        {
+            if (!_serial.Open())
+            {
+                EV.PostAlarmLog(this.Module, "Adixen Turbo Pump 串口无法打开");
+                return false;
+            }
+
+            _serial.OnDataChanged += OnPortDataChanged;
+            _serial.OnErrorHappened += OnErrorOccurred;
+
+            return true;
+        }
+
+        public override void Monitor()
+        {
+            if ((_queryWatch.ElapsedMilliseconds > _readInterval && _lastReadCommand == Operation.Invalid) || _queryWatch.ElapsedMilliseconds > _readTimeout)
+            {
+                SendCommand(Operation.GetCurrentValues);
+                _queryWatch.Restart();
+            }
+        }
+
+        public override void Reset()
+        {
+
+        }
+
+        public override void Terminate()
+        {
+            _serial?.Close();
+        }
+
+
+        private void OnErrorOccurred(string obj)
+        {
+            _noRepeatAlarm($"[{Module}] Adixen Turbo Pump serial port error: [{obj}]");
+        }
+
+        private void OnPortDataChanged(string obj)
+        {
+            if (string.IsNullOrEmpty(obj))
+            {
+                _noRepeatAlarm("Adixen Turbo Pump receive empty message");
+                return;
+            }
+
+            try
+            {
+                if (_rex_ok.Match(obj).Success)
+                    return;
+
+                if(_rex_err.Match(obj).Success)
+                {
+                    var errs = obj.Trim().Split(',');
+
+                    if(_comError.ContainsKey(errs[1]))
+                    {
+                        _noRepeatAlarm($"Adixen Turbo Pump communication error: {_comError[errs[1]]}");
+                    }
+                    else
+                    {
+                        _noRepeatAlarm($"Adixen Turbo Pump unknown communication error: {obj}");
+                    }
+
+                    _lastReadCommand = Operation.Invalid;
+                    return;
+                }
+
+                if(_lastReadCommand == Operation.Invalid)
+                {
+                    EV.PostWarningLog(Module, $"Adixen Turbo Pump unexpected communication data: {obj}");
+                    return;
+                }
+
+                var result_data = obj.Trim().Split(',');
+                switch(_lastReadCommand)
+                {
+                    case Operation.GetCurrentSpeed:
+                        var str_speed = result_data[1].Split();
+                        Speed = int.Parse(str_speed[0]);
+                        break;
+                }
+
+                _lastReadCommand = Operation.Invalid;
+
+            }
+            catch (Exception ex)
+            {
+                _noRepeatAlarm($"[{Module}] Adixen Turbo Pump error: [{ex.Message}], Data: {obj}");
+            }
+        }
+
+        public bool SendCommand(Operation op)
+        {
+            if (_noneParaCommandOp.ContainsKey(op))
+            {
+                var cmd = string.Format(_noneParaCommandOp[op], _address);
+                return _serial.Write(cmd);
+            }
+            else if (_readDataCommandOp.ContainsKey(op))
+            {
+                var cmd = string.Format(_readDataCommandOp[op], _address);
+                if(_serial.Write(cmd))
+                {
+                    _lastReadCommand = op;
+                    return true;
+                }
+            }
+
+            _noRepeatAlarm($"Adixen Turbo Pump: The {op} command need parameters");
+            return false;
+        }
+        public bool SendCommand(Operation op, int data)
+        {
+            if (_setDataCommandOp.ContainsKey(op))
+            {
+                var cmd = string.Format(_setDataCommandOp[op], _address, data);
+                return _sendCmd(cmd);
+            }
+
+            _noRepeatAlarm($"Adixen Turbo Pump: The command {op} does not need one parameter");
+            return false;
+        }
+
+        private bool _sendCmd(string cmd)
+        {
+            return _serial.Write(cmd);
+        }
+
+        private void _noRepeatAlarm(string alarm)
+        {
+            if(_lastAlarmString != alarm)
+            {
+                _lastAlarmString = alarm;
+                EV.PostAlarmLog(Module, alarm);
+            }
+        }
+    }
+}

+ 227 - 0
Venus/Venus_RT/Devices/ESC5HighVoltage.cs

@@ -0,0 +1,227 @@
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using MECF.Framework.Common.Communications;
+using MECF.Framework.Common.Equipment;
+
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.RT.Event;
+using Aitex.Core.RT.Device;
+
+namespace Venus_RT.Devices
+{
+    class ESC5HighVoltage : IDevice
+    {
+        public string Module { get; set; }
+        public string Name { get; set; }
+
+        public int OutputVoltage { get; set; }
+
+        public int CenterTapVoltage { get; set; }
+        public int PositiveOutputCurrent { get; set; }
+        public int NegativeOutputCurrent { get; set; }
+        public enum Operation
+        {
+            Attention,
+            Help,
+            SetOutputVoltage,
+            SetCurrentLimit,
+            EnableOutputVoltage,
+            DisableOutputVoltage,
+            SetUpRampTime,
+            SetDownRampTime,
+            ReadOutputVoltage,
+            ReadCenterTapVoltage,
+            ReadPositiveOutputCurrent,
+            ReadNegativeOutputCurrent,
+            EnableEcho,
+            DisableEcho,
+            EnableAutoDischarge,
+            DisableAutoDischarge,
+            EnableAutoVoltageReversal,
+            DisalbeAutoVoltageReversal,
+            ReadStatus,
+            Exit,
+            Invalid,
+        }
+
+        private readonly Dictionary<Operation, string> _noneParaCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.Attention,                   "!" },
+            {Operation.Help,                        "HM" },
+            {Operation.EnableOutputVoltage,         "EV" },
+            {Operation.DisableOutputVoltage,        "DV" },
+            {Operation.EnableEcho,                  "EE" },
+            {Operation.DisableEcho,                 "DE" },
+            {Operation.EnableAutoDischarge,         "D+" },
+            {Operation.DisableAutoDischarge,        "D-" },
+            {Operation.EnableAutoVoltageReversal,   "V+" },
+            {Operation.DisalbeAutoVoltageReversal,  "V-" },
+            {Operation.Exit,                        "EX" }
+        };
+
+        private readonly Dictionary<Operation, string> _readDataCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.ReadStatus,                  "SB" },
+            {Operation.ReadOutputVoltage,           "RV" },
+            {Operation.ReadCenterTapVoltage,        "RB" },
+            {Operation.ReadPositiveOutputCurrent,   "R+" },
+            {Operation.ReadNegativeOutputCurrent,   "R-" },
+        };
+
+        private readonly Dictionary<Operation, string> _setDataCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.SetOutputVoltage,            "SV{0:D4}" },
+            {Operation.SetCurrentLimit,             "SI{0:D4}" },
+            {Operation.SetDownRampTime,             "P-{0:D}" },
+            {Operation.SetUpRampTime,               "P+{0:D}" },
+        };
+
+        private readonly int _readInterval = 500;
+        private readonly int _readTimeout = 2000;
+        private readonly AsyncSerialPort _serial;
+        private Stopwatch _queryWatch = new Stopwatch();
+
+        private Operation _lastReadCommand = Operation.Invalid;
+        private string _lastAlarmString = string.Empty;
+
+        private Regex _rex = new Regex(@"[0-9]{1,4}");
+
+    public ESC5HighVoltage(ModuleName mod)
+        {
+            Module = mod.ToString();
+            var _PortNum = SC.GetStringValue($"{mod}.ElectrostaticVoltageSource.Port");
+            _serial = new AsyncSerialPort(_PortNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One);
+        }
+
+        public bool Initialize()
+        {
+            if (!_serial.Open())
+            {
+                _noRepeatAlarm("ESC-5 Electrostatic Voltage Source 串口无法打开");
+                return false;
+            }
+
+
+            _serial.OnDataChanged += OnPortDataChanged;
+            _serial.OnErrorHappened += OnErrorOccurred;
+
+            return true;
+        }
+
+        public void Monitor()
+        {
+            if ((_queryWatch.ElapsedMilliseconds > _readInterval && _lastReadCommand == Operation.Invalid) || _queryWatch.ElapsedMilliseconds > _readTimeout)
+            {
+                SendCommand(Operation.ReadOutputVoltage);
+                _queryWatch.Restart();
+            }
+        }
+
+        public void Reset()
+        {
+
+        }
+
+        public void Terminate()
+        {
+            _serial?.Close();
+        }
+
+
+        private void OnErrorOccurred(string obj)
+        {
+            _noRepeatAlarm($"[{Module}] ESC-5 Electrostatic Voltage Source error: [{obj}]");
+        }
+
+        private void OnPortDataChanged(string obj)
+        {
+            if (string.IsNullOrEmpty(obj))
+            {
+                _noRepeatAlarm("ESC-5 Electrostatic Voltage Source receive empty message");
+                return;
+            }
+
+            try
+            {
+                var data = _rex.Match(obj);
+                if(data.Success)
+                {
+                    int value = int.Parse(data.Value);
+                    switch(_lastReadCommand)
+                    {
+                        case Operation.ReadOutputVoltage:
+                            OutputVoltage = value;
+                            break;
+                        case Operation.ReadCenterTapVoltage:
+                            CenterTapVoltage = value;
+                            break;
+                        case Operation.ReadNegativeOutputCurrent:
+                            NegativeOutputCurrent = value;
+                            break;
+                        case Operation.ReadPositiveOutputCurrent:
+                            PositiveOutputCurrent = value;
+                            break;
+                    }
+
+                    _lastReadCommand = Operation.Invalid;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                _noRepeatAlarm($"[{Module}] ESC-5 Electrostatic Voltage Source error: [{ex.Message}], Data: {obj}");
+            }
+        }
+
+        public bool SendCommand(Operation op)
+        {
+            if (_noneParaCommandOp.ContainsKey(op))
+            {
+                return _serial.Write(_noneParaCommandOp[op]);
+            }
+            else if(_readDataCommandOp.ContainsKey(op))
+            {
+                if(_serial.Write(_readDataCommandOp[op]))
+                {
+                    _lastReadCommand = op;
+                    return true;
+                }
+            }
+
+            _noRepeatAlarm("This ESC-5 Electrostatic Voltage Source command need parameters");
+            return false;
+        }
+        public bool SendCommand(Operation op, int data)
+        {
+            if (_setDataCommandOp.ContainsKey(op))
+            {
+                var cmd = string.Format(_setDataCommandOp[op], data);
+                return _sendCmd(cmd);
+            }
+            else
+            {
+                _noRepeatAlarm("This ESC-5 Electrostatic Voltage Source command does not need 1 parameter");
+                return false;
+            }
+        }
+
+        private bool _sendCmd(string cmd)
+        {
+            return _serial.Write(cmd);
+        }
+
+        private void _noRepeatAlarm(string alarm)
+        {
+            if (_lastAlarmString != alarm)
+            {
+                _lastAlarmString = alarm;
+                EV.PostAlarmLog(Module, alarm);
+            }
+        }
+    }
+}

+ 357 - 0
Venus/Venus_RT/Devices/PendulumValve.cs

@@ -0,0 +1,357 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MECF.Framework.Common.Communications;
+using MECF.Framework.Common.Equipment;
+
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.RT.Event;
+using Aitex.Core.RT.Device;
+
+namespace Venus_RT.Devices
+{
+    class PendulumValve : IDevice
+    {
+        public enum Operation
+        {
+            SetPosition,
+            GetPositionSP,
+            Hold,
+            OpenValve,
+            CloseValve,
+            SetPressure,
+            GetPressureSP,
+            GetAssembly,
+            GetPosition,
+            GetPressure,
+            GetSensor1Data,
+            GetSensor2Data,
+            GetPressureCtrlStatus,
+            GetDeviceStatus,
+            GetWarnings,
+            GetSensorOffset,
+            GetSensor1Offset,
+            GetSensor2Offset,
+            GetLearnStatus,
+            GetLearnPressureLimit,
+            GetErrorStatus,
+            GetFatalErrorStatus,
+            GetThrottleCycleCounter,
+            GetIsolationCycleCounter,
+            GetPowerUpCounter,
+            GetHardwareConfiguration,
+            GetFirmwareConfiguration,
+            GetIdentification,
+            SetAccessMode,
+            SetInterfaceConfiguration,
+            SetValveConfiguration,
+            SetSensorConfiguration,
+            SetRangeConfiguration,
+            SetZero,
+            SetPressureAlignment,
+            SetLearn,
+            DownloadLearnData,
+            UploadLearnData,
+            SetPIDConfiguration,
+            GetPIDConfiguration,
+            SetValveSpeed,
+            GetValveSpeed,
+            Reset,
+            Invalid,
+        }
+
+        private readonly Dictionary<Operation, string> _noneParaCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.GetPositionSP,               "i:38" },
+            {Operation.Hold,                        "H:" },
+            {Operation.CloseValve,                  "C:" },
+            {Operation.OpenValve,                   "O:" },
+
+            {Operation.GetPressureSP,               "i:38" },
+            {Operation.GetAssembly,                 "i:76" },
+            {Operation.GetPosition,                 "A:" },
+            {Operation.GetPressure,                 "P:" },
+
+            {Operation.GetSensor1Data,              "i:64" },
+            {Operation.GetSensor2Data,              "i:65" },
+            {Operation.GetPressureCtrlStatus,       "i:36" },
+            {Operation.GetDeviceStatus,             "i:30" },
+
+            {Operation.GetWarnings,                 "i:35" },
+            {Operation.GetSensorOffset,             "i:62" },
+            {Operation.GetSensor1Offset,            "i:60" },
+            {Operation.GetSensor2Offset,            "i:61" },
+
+            {Operation.GetLearnStatus,              "i:32" },
+            {Operation.GetLearnPressureLimit,       "i:34" },
+            {Operation.GetErrorStatus,              "i:52" },
+            {Operation.GetFatalErrorStatus,         "i:50" },
+
+            {Operation.GetThrottleCycleCounter,     "i:70" },
+            {Operation.GetIsolationCycleCounter,    "i:71" },
+            {Operation.GetPowerUpCounter,           "i:72" },
+            {Operation.GetHardwareConfiguration,    "i:80" },
+
+            {Operation.GetFirmwareConfiguration,    "i:82" },
+            {Operation.GetIdentification,           "i:83" },
+        };
+
+        private readonly Dictionary<Operation, string> _singleParaCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.SetPosition,                 "R:{0:D6}" },
+            {Operation.SetPressure,                 "S:{0:D8}" },
+
+            {Operation.SetAccessMode,               "c:01{0:D2}" },
+            {Operation.SetInterfaceConfiguration,   "s:20{0:D8}" },
+
+            {Operation.SetValveConfiguration,       "s:04{0:D2}000000" },
+            {Operation.SetSensorConfiguration,      "s:01{0:D8}" },
+
+            {Operation.SetRangeConfiguration,       "s:21{0:D8}" },
+            {Operation.SetPressureAlignment,        "c:6002{0:D8}" },
+
+            {Operation.SetLearn,                    "L:{0:D8}" },
+            {Operation.UploadLearnData,             "u:{0:D3}" },
+
+            {Operation.SetPIDConfiguration,         "s:02{0:D8}" },
+            {Operation.SetValveSpeed,               "V:00{0:D4}" }
+        };
+
+        private readonly Dictionary<Operation, string> _twoParaCommandOp = new Dictionary<Operation, string>
+        {
+            {Operation.DownloadLearnData, "d:{0:D3}{1:D8}" }
+        };
+
+        private readonly Dictionary<string, string> _deviceError = new Dictionary<string, string>
+        {
+            {"000001",  "Parity error" },
+            {"000002",  "Input buffer overflow (to many characters) " },
+            {"000003",  "Framing error (data length, number of stop bits)" },
+            {"000010",  "<CR> or <LF> missing" },
+            {"000011",  ": missing" },
+            {"000012",  "Invalid number of characters (between : and [CR][LF])" },
+            {"000020",  "Unknown command" },
+            {"000021",  "Unknown command" },
+            {"000022",  "Invalid value" },
+            {"000023",  "Invalid value" },
+            {"000030",  "Value out of range" },
+            {"000041",  "Command not applicable for hardware configuration" },
+            {"000060",  "ZERO disabled" },
+            {"000080",  "Command not accepted due to local operation" },
+            {"000082",  "Command not accepted due to synchronization, CLOSED or OPEN by digital input, safety mode or fatal error" },
+        };
+
+
+        public string Module { get; set; }
+        public string Name { get; set; }
+
+        public int Pressure { get; set; }
+        public int Position { get; set; }
+
+        private readonly string EOF = "\r\n";
+        private readonly int _readInterval = 1000;
+        private readonly AsyncSerialPort _serial;
+        private Stopwatch _queryWatch = new Stopwatch();
+        private string _lastAlarmString = string.Empty;
+
+        public PendulumValve(ModuleName mod)
+        {
+            Module = mod.ToString();
+            var _PortNum = SC.GetStringValue($"{mod}.PendulumValve.Port");
+            _serial = new AsyncSerialPort(_PortNum, 9600, 7, System.IO.Ports.Parity.Even, System.IO.Ports.StopBits.One, EOF);
+        }
+
+        public bool Initialize()
+        {
+            if (!_serial.Open())
+            {
+                _noRepeatAlarm("Pendulum Valve 串口无法打开");
+                return false;
+            }
+
+
+            _serial.OnDataChanged += OnPortDataChanged;
+            _serial.OnErrorHappened += OnErrorOccurred;
+
+            return true;
+        }
+
+        public void Monitor()
+        {
+            if(_queryWatch.ElapsedMilliseconds > _readInterval)
+            {
+                SendCommand(Operation.GetPressure);
+                _queryWatch.Restart();
+            }
+        }
+
+        public void Reset()
+        {
+
+        }
+
+        public void Terminate()
+        {
+            _serial?.Close();
+        }
+
+        private void OnErrorOccurred(string obj)
+        {
+            _noRepeatAlarm($"[{Module}] VAT Pendulum Valve error: [{obj}]");
+        }
+
+        private void OnPortDataChanged(string obj)
+        {
+            if (string.IsNullOrEmpty(obj))
+            {
+                _noRepeatAlarm("VAT Pendulum Valve receive empty message");
+                return;
+            }    
+
+            try
+            {
+                var data = obj.TrimEnd().Split(':');
+                switch(data[0])
+                {
+                    case "P":
+                        {
+                            Pressure = int.Parse(data[1]);
+                        }
+                        break;
+                    case "A":
+                        {
+                            Position = int.Parse(data[1]);
+                        }
+                        break;
+                    case "i":
+                        {
+                            _tryParseInqueryData(obj);
+                        }
+                        break;
+                    case "E":
+                        {
+                            _noRepeatAlarm($"[{Module}] VAT Pendulum Valve device error: {_deviceError[data[1]]}");
+                        }
+                        break;
+                    default:
+                        {
+                            _noRepeatAlarm($"VAT Pendulum Valve: unrecognized received data: {obj}");
+                            break;
+                        }
+                }
+                
+            }
+            catch (Exception ex)
+            {
+                _noRepeatAlarm($"[{Module}] VAT Pendulum Valve error: [{ex.Message}], Data: {obj}");
+            }
+        }
+
+        public bool SendCommand(Operation op)
+        {
+            if(_noneParaCommandOp.ContainsKey(op))
+            {
+                return _serial.Write(_noneParaCommandOp[op] + EOF);
+            }
+            else
+            {
+                return false;
+            }
+        }
+        public bool SendCommand(Operation op, int data)
+        {
+            if(_singleParaCommandOp.ContainsKey(op))
+            {
+                var cmd = string.Format(_singleParaCommandOp[op], data) + EOF;
+                return _sendCmd(cmd);
+            }
+            else
+            {
+                _noRepeatAlarm("This VAT Pendulum Valve command need 1 data");
+                return false;
+            }
+        }
+
+        private bool _sendCmd(string cmd)
+        {
+            return _serial.Write(cmd);
+        }
+
+        private void _noRepeatAlarm(string alarm)
+        {
+            if (_lastAlarmString != alarm)
+            {
+                _lastAlarmString = alarm;
+                EV.PostAlarmLog(Module, alarm);
+            }
+        }
+
+        private bool _tryParseInqueryData(string data)
+        {
+            var cmdPrix = data.Substring(0, 4);
+
+            Operation oper = Operation.Invalid;
+            foreach( var item in _noneParaCommandOp)
+            {
+                if(item.Value == cmdPrix)
+                {
+                    oper = item.Key;
+                    break;
+                }
+            }
+
+            if( oper == Operation.Invalid)
+            {
+                return false; 
+            }
+
+            switch(oper)
+            {
+                case Operation.GetAssembly:
+                case Operation.GetDeviceStatus:
+                case Operation.GetLearnStatus:
+                case Operation.GetPressureCtrlStatus:
+                    {
+
+                    }
+                    break;
+                case Operation.GetIdentification:
+                case Operation.GetIsolationCycleCounter:
+                case Operation.GetPowerUpCounter:
+                case Operation.GetThrottleCycleCounter:
+                    {
+
+                    }
+                    break;
+                case Operation.GetWarnings:
+                case Operation.GetErrorStatus:
+                case Operation.GetFatalErrorStatus:
+                    {
+
+                    }
+                    break;
+                case Operation.GetFirmwareConfiguration:
+                case Operation.GetHardwareConfiguration:
+                case Operation.GetPIDConfiguration:
+                    {
+
+                    }
+                    break;
+                case Operation.GetSensor1Data:
+                case Operation.GetSensor2Data:
+                case Operation.GetSensor1Offset:
+                case Operation.GetSensor2Offset:
+                case Operation.GetSensorOffset:
+                    {
+
+                    }
+                    break;
+            }
+
+            return true;
+        }
+    }
+}

+ 3 - 0
Venus/Venus_RT/Venus_RT.csproj

@@ -71,12 +71,15 @@
     <Compile Include="Backends\IOMonitorView.xaml.cs">
       <DependentUpon>IOMonitorView.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Devices\AdixenTurboPump.cs" />
     <Compile Include="Devices\AdTecRF.cs" />
     <Compile Include="Devices\CometRF.cs" />
     <Compile Include="Devices\DataDefine.cs" />
     <Compile Include="Devices\DeviceManager.cs" />
     <Compile Include="Devices\EdwardsPump.cs" />
+    <Compile Include="Devices\ESC5HighVoltage.cs" />
     <Compile Include="Devices\KashiyamaPump.cs" />
+    <Compile Include="Devices\PendulumValve.cs" />
     <Compile Include="Devices\PlasmaController.cs" />
     <Compile Include="Devices\SkyPump.cs" />
     <Compile Include="Devices\SMCChiller.cs" />