Browse Source

添加并完善APC pid upload down功能

jiangjy 1 month ago
parent
commit
28900cf441

+ 87 - 0
Furnace/FurnaceRT/Config/IO/ELK/DeviceModelPM.xml

@@ -570,6 +570,12 @@
 					aoSlowVacuumI="AO_APCSlowVacuumI"
 					aoSlowVacuumD="AO_APCSlowVacuumD"
 					aoSlowVacuumA="AO_APCSlowVacuumA"
+			   
+			   		aiSlowVacuumP="AI_APCSlowVacuumP"
+					aiSlowVacuumI="AI_APCSlowVacuumI"
+					aiSlowVacuumD="AI_APCSlowVacuumD"
+					aiSlowVacuumA="AI_APCSlowVacuumA"
+			   
 					aoControllerModeSelect="AO_APCControllerModeSelect"
 					aoSpecifyTargetVacuumPressureControl="AO_APCSpecifyTargetVacuumPressureControl"
 					aoSpecifyTargetOpeningForValveOpeningControl="AO_APCSpecifyTargetOpeningForValveOpeningControl"
@@ -656,6 +662,87 @@
 					aoController10CL="AO_APCController10CL"
 					aoController10Offset="AO_APCController10Offset"
           
+			   	aiController1="AI_APCController1"
+				aiController1P="AI_APCController1P"
+				aiController1I="AI_APCController1I"
+				aiController1D="AI_APCController1D"
+				aiController1A="AI_APCController1A"
+				aiController1CH="AI_APCController1CH"
+				aiController1CL="AI_APCController1CL"
+				aiController1Offset="AI_APCController1Offset"
+				aiController2="AI_APCController2"
+				aiController2P="AI_APCController2P"
+				aiController2I="AI_APCController2I"
+				aiController2D="AI_APCController2D"
+				aiController2A="AI_APCController2A"
+				aiController2CH="AI_APCController2CH"
+				aiController2CL="AI_APCController2CL"
+				aiController2Offset="AI_APCController2Offset"
+				aiController3="AI_APCController3"
+				aiController3P="AI_APCController3P"
+				aiController3I="AI_APCController3I"
+				aiController3D="AI_APCController3D"
+				aiController3A="AI_APCController3A"
+				aiController3CH="AI_APCController3CH"
+				aiController3CL="AI_APCController3CL"
+				aiController3Offset="AI_APCController3Offset"
+				aiController4="AI_APCController4"
+				aiController4P="AI_APCController4P"
+				aiController4I="AI_APCController4I"
+				aiController4D="AI_APCController4D"
+				aiController4A="AI_APCController4A"
+				aiController4CH="AI_APCController4CH"
+				aiController4CL="AI_APCController4CL"
+				aiController4Offset="AI_APCController4Offset"
+				aiController5="AI_APCController5"
+				aiController5P="AI_APCController5P"
+				aiController5I="AI_APCController5I"
+				aiController5D="AI_APCController5D"
+				aiController5A="AI_APCController5A"
+				aiController5CH="AI_APCController5CH"
+				aiController5CL="AI_APCController5CL"
+				aiController5Offset="AI_APCController5Offset"
+				aiController6="AI_APCController6"
+				aiController6P="AI_APCController6P"
+				aiController6I="AI_APCController6I"
+				aiController6D="AI_APCController6D"
+				aiController6A="AI_APCController6A"
+				aiController6CH="AI_APCController6CH"
+				aiController6CL="AI_APCController6CL"
+				aiController6Offset="AI_APCController6Offset"
+				aiController7="AI_APCController7"
+				aiController7P="AI_APCController7P"
+				aiController7I="AI_APCController7I"
+				aiController7D="AI_APCController7D"
+				aiController7A="AI_APCController7A"
+				aiController7CH="AI_APCController7CH"
+				aiController7CL="AI_APCController7CL"
+				aiController7Offset="AI_APCController7Offset"
+				aiController8="AI_APCController8"
+				aiController8P="AI_APCController8P"
+				aiController8I="AI_APCController8I"
+				aiController8D="AI_APCController8D"
+				aiController8A="AI_APCController8A"
+				aiController8CH="AI_APCController8CH"
+				aiController8CL="AI_APCController8CL"
+				aiController8Offset="AI_APCController8Offset"
+				aiController9="AI_APCController9"
+				aiController9P="AI_APCController9P"
+				aiController9I="AI_APCController9I"
+				aiController9D="AI_APCController9D"
+				aiController9A="AI_APCController9A"
+				aiController9CH="AI_APCController9CH"
+				aiController9CL="AI_APCController9CL"
+				aiController9Offset="AI_APCController9Offset"
+				aiController10="AI_APCController10"
+				aiController10P="AI_APCController10P"
+				aiController10I="AI_APCController10I"
+				aiController10D="AI_APCController10D"
+				aiController10A="AI_APCController10A"
+				aiController10CH="AI_APCController10CH"
+				aiController10CL="AI_APCController10CL"
+				aiController10Offset="AI_APCController10Offset"
+          
 					scRootPath=""
 					aioType="float"
 				/>

+ 263 - 26
Furnace/FurnaceRT/Devices/IoAPC.cs

@@ -20,6 +20,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
@@ -28,6 +29,8 @@ namespace FurnaceRT.Devices
 {
     public class IoAPC : BaseDevice, IDevice
     {
+        private Dictionary<string, Dictionary<string, string>> _pIDFileInfo = new Dictionary<string, Dictionary<string, string>>();
+
         #region Filed
         private DIAccessor _diP1ZeroOffsetOutRangeAlm;
         private DIAccessor _diP1ZeroAdjOutRangeAlm;
@@ -46,7 +49,7 @@ namespace FurnaceRT.Devices
         private DIAccessor _diPumpStopInterlockAlm;
         private DIAccessor _diAutoTeachingErr1Alm;
         private DIAccessor _diAutoTeachingErr2Alm;
-        
+
         private DOAccessor _doVGUnit;
         private DOAccessor _doAoDataReadSysConfig;
         private DOAccessor _doAoDataWriteSysConfig;
@@ -187,6 +190,91 @@ namespace FurnaceRT.Devices
         private AOAccessor _aoController10CL;
         private AOAccessor _aoController10Offset;
 
+
+        private AIAccessor _aiController1P;
+        private AIAccessor _aiController1I;
+        private AIAccessor _aiController1D;
+        private AIAccessor _aiController1A;
+        private AIAccessor _aiController1CH;
+        private AIAccessor _aiController1CL;
+        private AIAccessor _aiController1Offset;
+        private AIAccessor _aiController2;
+        private AIAccessor _aiController2P;
+        private AIAccessor _aiController2I;
+        private AIAccessor _aiController2D;
+        private AIAccessor _aiController2A;
+        private AIAccessor _aiController2CH;
+        private AIAccessor _aiController2CL;
+        private AIAccessor _aiController2Offset;
+        private AIAccessor _aiController3;
+        private AIAccessor _aiController3P;
+        private AIAccessor _aiController3I;
+        private AIAccessor _aiController3D;
+        private AIAccessor _aiController3A;
+        private AIAccessor _aiController3CH;
+        private AIAccessor _aiController3CL;
+        private AIAccessor _aiController3Offset;
+        private AIAccessor _aiController4;
+        private AIAccessor _aiController4P;
+        private AIAccessor _aiController4I;
+        private AIAccessor _aiController4D;
+        private AIAccessor _aiController4A;
+        private AIAccessor _aiController4CH;
+        private AIAccessor _aiController4CL;
+        private AIAccessor _aiController4Offset;
+        private AIAccessor _aiController5;
+        private AIAccessor _aiController5P;
+        private AIAccessor _aiController5I;
+        private AIAccessor _aiController5D;
+        private AIAccessor _aiController5A;
+        private AIAccessor _aiController5CH;
+        private AIAccessor _aiController5CL;
+        private AIAccessor _aiController5Offset;
+        private AIAccessor _aiController6;
+        private AIAccessor _aiController6P;
+        private AIAccessor _aiController6I;
+        private AIAccessor _aiController6D;
+        private AIAccessor _aiController6A;
+        private AIAccessor _aiController6CH;
+        private AIAccessor _aiController6CL;
+        private AIAccessor _aiController6Offset;
+        private AIAccessor _aiController7;
+        private AIAccessor _aiController7P;
+        private AIAccessor _aiController7I;
+        private AIAccessor _aiController7D;
+        private AIAccessor _aiController7A;
+        private AIAccessor _aiController7CH;
+        private AIAccessor _aiController7CL;
+        private AIAccessor _aiController7Offset;
+        private AIAccessor _aiController8;
+        private AIAccessor _aiController8P;
+        private AIAccessor _aiController8I;
+        private AIAccessor _aiController8D;
+        private AIAccessor _aiController8A;
+        private AIAccessor _aiController8CH;
+        private AIAccessor _aiController8CL;
+        private AIAccessor _aiController8Offset;
+        private AIAccessor _aiController9;
+        private AIAccessor _aiController9P;
+        private AIAccessor _aiController9I;
+        private AIAccessor _aiController9D;
+        private AIAccessor _aiController9A;
+        private AIAccessor _aiController9CH;
+        private AIAccessor _aiController9CL;
+        private AIAccessor _aiController9Offset;
+        private AIAccessor _aiController10;
+        private AIAccessor _aiController10P;
+        private AIAccessor _aiController10I;
+        private AIAccessor _aiController10D;
+        private AIAccessor _aiController10A;
+        private AIAccessor _aiController10CH;
+        private AIAccessor _aiController10CL;
+        private AIAccessor _aiController10Offset;
+        private AIAccessor _aiSlowVacuumP;
+        private AIAccessor _aiSlowVacuumI;
+        private AIAccessor _aiSlowVacuumD;
+        private AIAccessor _aiSlowVacuumA;
+
         private bool _isFloatAioType = false;
         private AITAPCData _deviceData;
 
@@ -217,7 +305,7 @@ namespace FurnaceRT.Devices
         {
             get
             {
-                if(_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000)
+                if (_unloadTimer != null && _unloadTimer.IsRunning && _unloadTimer.ElapsedMilliseconds > 3000)
                 {
                     return _aiValveStatusThreshold.FloatValue;
                 }
@@ -446,6 +534,10 @@ namespace FurnaceRT.Devices
             _aoSlowVacuumI = ParseAoNode("aoSlowVacuumI", node, ioModule);
             _aoSlowVacuumD = ParseAoNode("aoSlowVacuumD", node, ioModule);
             _aoSlowVacuumA = ParseAoNode("aoSlowVacuumA", node, ioModule);
+            _aiSlowVacuumP = ParseAiNode("aiSlowVacuumP", node, ioModule);
+            _aiSlowVacuumI = ParseAiNode("aiSlowVacuumI", node, ioModule);
+            _aiSlowVacuumD = ParseAiNode("aiSlowVacuumD", node, ioModule);
+            _aiSlowVacuumA = ParseAiNode("aiSlowVacuumA", node, ioModule);
             _aoControllerModeSelect = ParseAoNode("aoControllerModeSelect", node, ioModule);
             _aoSpecifyTargetVacuumPressureControl = ParseAoNode("aoSpecifyTargetVacuumPressureControl", node, ioModule);
             _aoSpecifyTargetOpeningForValveOpeningControl = ParseAoNode("aoSpecifyTargetOpeningForValveOpeningControl", node, ioModule);
@@ -532,6 +624,86 @@ namespace FurnaceRT.Devices
             _aoController10CL = ParseAoNode("aoController10CL", node, ioModule);
             _aoController10Offset = ParseAoNode("aoController10Offset", node, ioModule);
 
+            _aiController1P = ParseAiNode("aiController1P", node, ioModule);
+            _aiController1I = ParseAiNode("aiController1I", node, ioModule);
+            _aiController1D = ParseAiNode("aiController1D", node, ioModule);
+            _aiController1A = ParseAiNode("aiController1A", node, ioModule);
+            _aiController1CH = ParseAiNode("aiController1CH", node, ioModule);
+            _aiController1CL = ParseAiNode("aiController1CL", node, ioModule);
+            _aiController1Offset = ParseAiNode("aiController1Offset", node, ioModule);
+            _aiController2 = ParseAiNode("aiController2", node, ioModule);
+            _aiController2P = ParseAiNode("aiController2P", node, ioModule);
+            _aiController2I = ParseAiNode("aiController2I", node, ioModule);
+            _aiController2D = ParseAiNode("aiController2D", node, ioModule);
+            _aiController2A = ParseAiNode("aiController2A", node, ioModule);
+            _aiController2CH = ParseAiNode("aiController2CH", node, ioModule);
+            _aiController2CL = ParseAiNode("aiController2CL", node, ioModule);
+            _aiController2Offset = ParseAiNode("aiController2Offset", node, ioModule);
+            _aiController3 = ParseAiNode("aiController3", node, ioModule);
+            _aiController3P = ParseAiNode("aiController3P", node, ioModule);
+            _aiController3I = ParseAiNode("aiController3I", node, ioModule);
+            _aiController3D = ParseAiNode("aiController3D", node, ioModule);
+            _aiController3A = ParseAiNode("aiController3A", node, ioModule);
+            _aiController3CH = ParseAiNode("aiController3CH", node, ioModule);
+            _aiController3CL = ParseAiNode("aiController3CL", node, ioModule);
+            _aiController3Offset = ParseAiNode("aiController3Offset", node, ioModule);
+            _aiController4 = ParseAiNode("aiController4", node, ioModule);
+            _aiController4P = ParseAiNode("aiController4P", node, ioModule);
+            _aiController4I = ParseAiNode("aiController4I", node, ioModule);
+            _aiController4D = ParseAiNode("aiController4D", node, ioModule);
+            _aiController4A = ParseAiNode("aiController4A", node, ioModule);
+            _aiController4CH = ParseAiNode("aiController4CH", node, ioModule);
+            _aiController4CL = ParseAiNode("aiController4CL", node, ioModule);
+            _aiController4Offset = ParseAiNode("aiController4Offset", node, ioModule);
+            _aiController5 = ParseAiNode("aiController5", node, ioModule);
+            _aiController5P = ParseAiNode("aiController5P", node, ioModule);
+            _aiController5I = ParseAiNode("aiController5I", node, ioModule);
+            _aiController5D = ParseAiNode("aiController5D", node, ioModule);
+            _aiController5A = ParseAiNode("aiController5A", node, ioModule);
+            _aiController5CH = ParseAiNode("aiController5CH", node, ioModule);
+            _aiController5CL = ParseAiNode("aiController5CL", node, ioModule);
+            _aiController5Offset = ParseAiNode("aiController5Offset", node, ioModule);
+            _aiController6 = ParseAiNode("aiController6", node, ioModule);
+            _aiController6P = ParseAiNode("aiController6P", node, ioModule);
+            _aiController6I = ParseAiNode("aiController6I", node, ioModule);
+            _aiController6D = ParseAiNode("aiController6D", node, ioModule);
+            _aiController6A = ParseAiNode("aiController6A", node, ioModule);
+            _aiController6CH = ParseAiNode("aiController6CH", node, ioModule);
+            _aiController6CL = ParseAiNode("aiController6CL", node, ioModule);
+            _aiController6Offset = ParseAiNode("aiController6Offset", node, ioModule);
+            _aiController7 = ParseAiNode("aiController7", node, ioModule);
+            _aiController7P = ParseAiNode("aiController7P", node, ioModule);
+            _aiController7I = ParseAiNode("aiController7I", node, ioModule);
+            _aiController7D = ParseAiNode("aiController7D", node, ioModule);
+            _aiController7A = ParseAiNode("aiController7A", node, ioModule);
+            _aiController7CH = ParseAiNode("aiController7CH", node, ioModule);
+            _aiController7CL = ParseAiNode("aiController7CL", node, ioModule);
+            _aiController7Offset = ParseAiNode("aiController7Offset", node, ioModule);
+            _aiController8 = ParseAiNode("aiController8", node, ioModule);
+            _aiController8P = ParseAiNode("aiController8P", node, ioModule);
+            _aiController8I = ParseAiNode("aiController8I", node, ioModule);
+            _aiController8D = ParseAiNode("aiController8D", node, ioModule);
+            _aiController8A = ParseAiNode("aiController8A", node, ioModule);
+            _aiController8CH = ParseAiNode("aiController8CH", node, ioModule);
+            _aiController8CL = ParseAiNode("aiController8CL", node, ioModule);
+            _aiController8Offset = ParseAiNode("aiController8Offset", node, ioModule);
+            _aiController9 = ParseAiNode("aiController9", node, ioModule);
+            _aiController9P = ParseAiNode("aiController9P", node, ioModule);
+            _aiController9I = ParseAiNode("aiController9I", node, ioModule);
+            _aiController9D = ParseAiNode("aiController9D", node, ioModule);
+            _aiController9A = ParseAiNode("aiController9A", node, ioModule);
+            _aiController9CH = ParseAiNode("aiController9CH", node, ioModule);
+            _aiController9CL = ParseAiNode("aiController9CL", node, ioModule);
+            _aiController9Offset = ParseAiNode("aiController9Offset", node, ioModule);
+            _aiController10 = ParseAiNode("aiController10", node, ioModule);
+            _aiController10P = ParseAiNode("aiController10P", node, ioModule);
+            _aiController10I = ParseAiNode("aiController10I", node, ioModule);
+            _aiController10D = ParseAiNode("aiController10D", node, ioModule);
+            _aiController10A = ParseAiNode("aiController10A", node, ioModule);
+            _aiController10CH = ParseAiNode("aiController10CH", node, ioModule);
+            _aiController10CL = ParseAiNode("aiController10CL", node, ioModule);
+            _aiController10Offset = ParseAiNode("aiController10Offset", node, ioModule);
+
             PressureUnit = SC.GetStringValue($"{Module}.{Name}.PressureUnit");
         }
         public bool Initialize()
@@ -578,6 +750,7 @@ namespace FurnaceRT.Devices
             DATA.Subscribe($"{Module}.{Name}.InterlockConstantOfInterlock3", () => InterlockConstantOfInterlock3);
             DATA.Subscribe($"{Module}.{Name}.P1SensorOffsetSetting", () => P1SensorOffsetSetting);
             DATA.Subscribe($"{Module}.{Name}.PosMonOffsetSetting", () => PosMonOffsetSetting);
+            DATA.Subscribe($"{Module}.{Name}.AllPIDFileInfo", () => _pIDFileInfo);
             //DATA.Subscribe($"{Module}.{Name}.IsSwitch", () => IsSwitch);
             //DATA.Subscribe($"{Module}.{Name}.SetSpeed", () => SetSpeed);
             //DATA.Subscribe($"{Module}.{Name}.MaxSpeed", () => MaxSpeed);
@@ -622,12 +795,21 @@ namespace FurnaceRT.Devices
                 SetConfig(param);
                 return true;
             });
+            OP.Subscribe($"{Module}.{Name}.GetAllPIDFileInfo", (string cmd, object[] param) =>
+            {
+                //command;pidTable;setValue;LowPressWait
+
+                _pIDFileInfo = GetAllPID();
+
+                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);
+                    SetSlowVacParameters(param[0].ToString());
                 }
                 return true;
             });
@@ -648,6 +830,61 @@ namespace FurnaceRT.Devices
             _unloadTimer.Restart();
             _doAoDataReadSysConfig.SetPulseValue(true, 3000);
         }
+        public Dictionary<string, Dictionary<string, string>> GetAllPID()
+        {
+            _pIDFileInfo.Clear();
+            FieldInfo[] fields = typeof(IoAPC).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
+            Dictionary<string, FieldInfo> fieldCache = new Dictionary<string, FieldInfo>();
+
+            for (int i = 1; i <= 10; i++)
+            {
+                var prefix = $"_aiController{i}";
+                var aiControllerP = GetFieldValue(prefix + "P", fields, fieldCache) as AIAccessor;
+                var aiControllerI = GetFieldValue(prefix + "I", fields, fieldCache) as AIAccessor;
+                var aiControllerD = GetFieldValue(prefix + "D", fields, fieldCache) as AIAccessor;
+                var aiControllerA = GetFieldValue(prefix + "A", fields, fieldCache) as AIAccessor;
+                var aiControllerCH = GetFieldValue(prefix + "CH", fields, fieldCache) as AIAccessor;
+                var aiControllerCL = GetFieldValue(prefix + "CL", fields, fieldCache) as AIAccessor;
+                var aiControllerOffset = GetFieldValue(prefix + "Offset", fields, fieldCache) as AIAccessor;
+
+                _pIDFileInfo.Add(i.ToString(), new Dictionary<string, string>()
+                     {
+                         { "P", aiControllerP != null ? aiControllerP.FloatValue.ToString() : "0" },
+                         { "I", aiControllerI != null ? aiControllerI.FloatValue.ToString() : "0" },
+                         { "D", aiControllerD != null ? aiControllerD.FloatValue.ToString() : "0" },
+                         { "A", aiControllerA != null ? aiControllerA.FloatValue.ToString() : "0" },
+                         { "CH", aiControllerCH != null ? aiControllerCH.FloatValue.ToString() : "0" },
+                         { "CL", aiControllerCL != null ? aiControllerCL.FloatValue.ToString() : "0" },
+                         { "Offset", aiControllerOffset != null ? aiControllerOffset.FloatValue.ToString() : "0" }
+                     });
+                 }
+
+            var aiSlowVacuumP = _aiSlowVacuumP?.FloatValue;
+            var aiSlowVacuumI = _aiSlowVacuumI?.FloatValue;
+            var aiSlowVacuumD = _aiSlowVacuumD?.FloatValue;
+            var aiSlowVacuumA = _aiSlowVacuumA?.FloatValue;
+
+            _pIDFileInfo.Add("0", new Dictionary<string, string>()
+                {
+                    { "P", aiSlowVacuumP != null ? aiSlowVacuumP.ToString() : "0" },
+                    { "I", aiSlowVacuumI != null ? aiSlowVacuumI.ToString() : "0" },
+                    { "D", aiSlowVacuumD != null ? aiSlowVacuumD.ToString() : "0" },
+                    { "A", aiSlowVacuumA != null ? aiSlowVacuumA.ToString() : "0" }
+                });
+
+            _doAoDataReadCusConfig?.SetPulseValue(true, 3000);
+
+            return _pIDFileInfo;
+        }
+        private object GetFieldValue(string fieldName, FieldInfo[] fields, Dictionary<string, FieldInfo> fieldCache)
+        {
+            if (!fieldCache.TryGetValue(fieldName, out FieldInfo field))
+            {
+                field = Array.Find(fields, f => f.Name == fieldName);
+                fieldCache[fieldName] = field;
+            }
+            return field?.GetValue(this);
+        }
         private void SetDownload(object[] param)
         {
             SetConfig(param);
@@ -682,7 +919,7 @@ namespace FurnaceRT.Devices
         }
         private void SetConfig(object[] param)
         {
-            if(param != null && param.Length > 7)
+            if (param != null && param.Length > 7)
             {
                 float.TryParse(param[0].ToString(), out float value);
                 ValveStatusThreshold = value;
@@ -697,7 +934,7 @@ namespace FurnaceRT.Devices
                 Interlock2 = value;
 
                 float.TryParse(param[4].ToString(), out value);
-                Interlock3= value;
+                Interlock3 = value;
 
                 float.TryParse(param[5].ToString(), out value);
                 InterlockConstantOfInterlock3 = value;
@@ -712,12 +949,12 @@ namespace FurnaceRT.Devices
 
         public void Monitor()
         {
-            if(!_isInit)
+            if (!_isInit)
             {
                 if (!_initTimer.IsRunning)
                     _initTimer.Start();
 
-                if(_initTimer.ElapsedMilliseconds > 5 * 1000)
+                if (_initTimer.ElapsedMilliseconds > 5 * 1000)
                 {
                     _initTimer.Stop();
                     _isInit = true;
@@ -726,7 +963,7 @@ namespace FurnaceRT.Devices
                     SetControllerParameters(pidTableName, controllerID);
                 }
             }
-            if(_valveAV71 == null)
+            if (_valveAV71 == null)
                 _valveAV71 = DEVICE.GetDevice<IoValve>($"{Module}.ValveAV71");
 
             //if(_valveAV71 != null && Singleton<EquipmentManager>.Instance.Modules.ContainsKey(ModuleName.PM1) &&
@@ -749,7 +986,7 @@ namespace FurnaceRT.Devices
             //    }
             //}
 
-            if(_apcSetModeTimer.IsRunning && _apcSetModeTimer.ElapsedMilliseconds > _apcSetModeTimeOutSec * 1000)
+            if (_apcSetModeTimer.IsRunning && _apcSetModeTimer.ElapsedMilliseconds > _apcSetModeTimeOutSec * 1000)
             {
                 APCSetModeAlarm.Set("APC set mode timeout");
             }
@@ -926,7 +1163,7 @@ namespace FurnaceRT.Devices
             _deviceData.PIDTable = $"{controllerID}:{paras[10]}";
             _deviceData.LowPressWaitSetPoint = paras[3];
 
-            if(av71 == "close")
+            if (av71 == "close")
             {
                 //av71 close,就设置为close
                 _valveAV71.TurnValve(false, out _);
@@ -956,13 +1193,13 @@ namespace FurnaceRT.Devices
         }
         private void SetManualParameters(object[] param)
         {
-            if(param == null || param.Length < 1)
+            if (param == null || param.Length < 1)
             {
                 EV.PostWarningLog(Module, $"Invalid APC set parameter");
                 return;
             }
             var paras = param[0].ToString().Split(';');
-            if(paras.Length < 4)
+            if (paras.Length < 4)
             {
                 EV.PostWarningLog(Module, $"Invalid APC set parameter");
                 return;
@@ -974,7 +1211,7 @@ namespace FurnaceRT.Devices
             bool av71 = _valveAV71.Status;
             if (paras.Length > 4)
                 bool.TryParse(paras[4], out av71);
-            
+
             //小于 10 torr, full open或者根据设定的模式
             //大于10 torr,5秒内需要设定的模式
             if (av71)
@@ -998,7 +1235,7 @@ namespace FurnaceRT.Devices
                 command = "Full Close";
                 _apcSetModeTimer.Stop();
             }
-            
+
             if (command.ToLower() == "none")
                 return;
 
@@ -1015,7 +1252,7 @@ namespace FurnaceRT.Devices
                     int.TryParse(pidTables[1], out controllerID);
                 }
             }
-            
+
             float.TryParse(paras[2], out float setValue);
             _deviceData.SetPoint = setValue;
             _deviceData.CommandSetPoint = command;
@@ -1024,7 +1261,7 @@ namespace FurnaceRT.Devices
 
             SetCommandParameters(command, setValue, pidTableName, controllerID);
         }
-        private void SetCommandParameters(string command, float setValue, string pidTableName, int controllerID, string recipePIDTableName="")
+        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)
@@ -1197,7 +1434,7 @@ namespace FurnaceRT.Devices
         private void SetControllerParameters(string fileNameAndPath, int controllerID, string recipePIDTableName = "")
         {
             //var defaultPID = SC.GetStringValue("PM1.APCPID");
-            if(string.IsNullOrEmpty(fileNameAndPath))
+            if (string.IsNullOrEmpty(fileNameAndPath))
             {
                 fileNameAndPath = SC.GetStringValue("PM1.APCPID");
             }
@@ -1211,11 +1448,11 @@ namespace FurnaceRT.Devices
                 EV.PostWarningLog(Module, $"{fileNameAndPath} APC PID name is empty");
                 return;
             }
-            var fileName = string.Join( "\\", para.ToArray());
+            var fileName = string.Join("\\", para.ToArray());
             if (!string.IsNullOrEmpty(recipePIDTableName))
                 fileName = recipePIDTableName;
 
-            if(controllerID <= 0)
+            if (controllerID <= 0)
             {
                 int.TryParse(SC.GetStringValue("PM1.APCPIDControllerID"), out controllerID);
             }
@@ -1233,7 +1470,7 @@ namespace FurnaceRT.Devices
             XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
             if (nodeSteps == null)
                 nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
-            if(nodeSteps == null)
+            if (nodeSteps == null)
             {
                 EV.PostWarningLog(Module, $"Invalid APC PID file {fileNameAndPath}");
                 return;
@@ -1265,7 +1502,7 @@ namespace FurnaceRT.Devices
                 float.TryParse(parameters["offset"], out offset);
                 float.TryParse(parameters["CH"], out ch);
                 float.TryParse(parameters["CL"], out cl);
-                if(dic.ContainsKey(no))
+                if (dic.ContainsKey(no))
                 {
                     EV.PostWarningLog(Module, $"Invalid APC PID file {fileNameAndPath}, duplicate no={no}");
                     return;
@@ -1290,7 +1527,7 @@ namespace FurnaceRT.Devices
             }
             if (!dic.ContainsKey(controllerID))
                 return;
-                
+
             p = dic[controllerID].P;
             i = dic[controllerID].I;
             d = dic[controllerID].D;
@@ -1298,7 +1535,7 @@ namespace FurnaceRT.Devices
             ch = dic[controllerID].CH;
             cl = dic[controllerID].CL;
             offset = dic[controllerID].Offset;
-            switch(controllerID)
+            switch (controllerID)
             {
                 case 1:
                     _aoController1P.FloatValue = p;
@@ -1403,7 +1640,7 @@ namespace FurnaceRT.Devices
         public bool CheckWaitCondition(out string reason)
         {
             reason = "";
-            if(IsNeedWaitComplete)
+            if (IsNeedWaitComplete)
             {
                 var command = _deviceData.CommandSetPoint;
                 var setValue = _deviceData.SetPoint;
@@ -1425,7 +1662,7 @@ namespace FurnaceRT.Devices
                     case "Press2":
                         if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Press2Control &&
                           ((_deviceData.Pressure2Feedback > _deviceData.PressureSetPoint - _waitLow &&
-                            _deviceData.Pressure2Feedback < _deviceData.PressureSetPoint + _waitHigh )||
+                            _deviceData.Pressure2Feedback < _deviceData.PressureSetPoint + _waitHigh) ||
                             (_waitLow <= 0 && _waitHigh <= 0)))
                         {
                             return true;
@@ -1447,7 +1684,7 @@ namespace FurnaceRT.Devices
                         break;
                     case "Valve Angle":
                         if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.PositionControl &&
-                           ((_deviceData.PositionFeedback > _waitLow && _deviceData.PositionFeedback < _waitHigh )||
+                           ((_deviceData.PositionFeedback > _waitLow && _deviceData.PositionFeedback < _waitHigh) ||
                            (_waitLow <= 0 && _waitHigh <= 0)))
                         {
                             return true;
@@ -1458,7 +1695,7 @@ namespace FurnaceRT.Devices
                         }
                         break;
                     case "Full Open":
-                        if(_deviceData.ModeSetPoint== _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Open)
+                        if (_deviceData.ModeSetPoint == _deviceData.ModeFeedback && _deviceData.ModeSetPoint == (int)PressureControlMode.Open)
                         {
                             return true;
                         }

+ 1 - 1
Furnace/FurnaceUI/Views/Parameter/APCPIDEditView.xaml

@@ -206,7 +206,7 @@
                     </i:EventTrigger>
                 </i:Interaction.Triggers>
             </Button>
-            <Button Content="Download"  Width="95" Margin="2"  Style="{StaticResource CommandButton}" IsEnabled="{Binding IsEnable}">
+            <Button Content="Download"  Width="95" Margin="2"  Style="{StaticResource CommandButton}" IsEnabled="{Binding DownloadEnable}">
                 <i:Interaction.Triggers>
                     <i:EventTrigger EventName="Click">
                         <cal:ActionMessage MethodName="ParameterDownload">

+ 46 - 0
Furnace/FurnaceUI/Views/Parameter/APCPIDEditViewModel.cs

@@ -158,7 +158,17 @@ namespace FurnaceUI.Views.Parameter
                 NotifyOfPropertyChange("PrevStepInsertIsEnabled");
             }
         }
+        private bool _DownloadEnable = true;
 
+        public bool DownloadEnable
+        {
+            get => _DownloadEnable;
+            set
+            {
+                _DownloadEnable = value;
+                NotifyOfPropertyChange(nameof(DownloadEnable));
+            }
+        }
         private bool _prevStepItemIsEnabled;
 
         public bool PrevStepItemIsEnabled
@@ -626,12 +636,48 @@ namespace FurnaceUI.Views.Parameter
 
         public void ParameterDownload()
         {
+            if (DialogButton.No == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,
+                        DialogType.CONFIRM,
+                        $"Confirm the issuance of PID data for the current step?"))
+            {
+                return;
+            }
             var step = CurrentParameter.Steps.FirstOrDefault(x => x.IsChecked);
             InvokeClient.Instance.Service.DoOperation($"PM1.APC.SetPID", $"{FullFileName}", step.StepNo);
         }
 
         public void ParameterUnload()
         {
+            if (DialogButton.No == DialogBox.ShowDialog(DialogButton.Yes | DialogButton.No,
+                        DialogType.CONFIRM,
+                        $"Read PID data to UI? Please save!"))
+            {
+                return;
+            }
+            DownloadEnable = false;
+            InvokeClient.Instance.Service.DoOperation("PM1.APC.GetAllPIDFileInfo");
+            var allAPCPID = (Dictionary<string, Dictionary<string, string>>)QueryDataClient.Instance.Service.GetData("PM1.APC.AllPIDFileInfo");
+            if (allAPCPID != null && allAPCPID.Count > 0)
+            {
+
+                foreach (var item in CurrentParameter.Steps)
+                {
+                    if (allAPCPID.TryGetValue(item.StepNo.ToString(), out var dataItem))
+                    {
+                        ((APCPIDTable)item).P.SetValue(dataItem["P"]);
+                        ((APCPIDTable)item).I.SetValue(dataItem["I"]);
+                        ((APCPIDTable)item).D.SetValue(dataItem["D"]);
+                        ((APCPIDTable)item).A.SetValue(dataItem["A"]);
+                        ((APCPIDTable)item).CH.SetValue(dataItem["CH"]);
+                        ((APCPIDTable)item).CL.SetValue(dataItem["CL"]);
+                        ((APCPIDTable)item).Offset.SetValue(dataItem["Offset"]);
+                    }
+                }
+                CurrentParameter.SlowVacP.SetValue(allAPCPID.LastOrDefault().Value["P"]);
+                CurrentParameter.SlowVacI.SetValue(allAPCPID.LastOrDefault().Value["I"]);
+                CurrentParameter.SlowVacD.SetValue(allAPCPID.LastOrDefault().Value["D"]);
+                CurrentParameter.SlowVacA.SetValue(allAPCPID.LastOrDefault().Value["A"]);
+            }
 
         }