From 1bc2df66bc88a6405df345dccc24a5031e18b592 Mon Sep 17 00:00:00 2001
From: patrick.xu <patrick.xu@broconcentric.com>
Date: 星期一, 21 十二月 2020 09:54:48 +0800
Subject: [PATCH] 1. gocator添加byte2/byte4的配置,目前测试byte4不成功,暂时还是使用byte2配置。 2. 添加键名代码映射配置和NG键名代码上传功能

---
 src/Bro.Device.GTSCard/GTSCardDriver.cs              |   12 +
 src/Bro.M071.Process/UI/M071_MainForm.cs             |    4 
 src/Bro.Device.HikCamera/Bro.Device.HikCamera.csproj |    2 
 src/Bro.M071.Process/M071Process_MES.cs              |   66 ++++++-
 src/Bro.Process/ProcessControl.cs                    |    8 
 src/Bro.Device.Gocator/GocatorConfig.cs              |   10 +
 src/Bro.M071.Process/M071Process.cs                  |  218 +++++++++++++++--------
 src/Bro.Device.Gocator/GocatorDriver.cs              |   82 +++++----
 src/Bro.M071.Process/Bro.M071.Process.csproj         |   13 -
 src/Bro.M071.Process/M071Config.cs                   |   59 ++++++
 src/Bro.M071.Process/M071Models.cs                   |   22 ++
 src/Bro.M071.Process/UI/KeyIndicator.cs              |    2 
 src/ExcelTest/ExcelTest.csproj                       |    4 
 13 files changed, 353 insertions(+), 149 deletions(-)

diff --git a/src/Bro.Device.GTSCard/GTSCardDriver.cs b/src/Bro.Device.GTSCard/GTSCardDriver.cs
index dbea577..303ddb4 100644
--- a/src/Bro.Device.GTSCard/GTSCardDriver.cs
+++ b/src/Bro.Device.GTSCard/GTSCardDriver.cs
@@ -646,7 +646,9 @@
                 if (CurrentState != EnumHelper.DeviceState.DSOpen)
                 {
                     LogAsync(DateTime.Now, "闈炴甯哥姸鎬佸紓甯�", "杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�");
-                    throw new ProcessException("杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�", null);
+
+                    return false;
+                    //throw new ProcessException("杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�", null);
                 }
 
                 LogAsync(DateTime.Now, "杞�" + optionPara.AxisIndex + "寮�濮嬭繍鍔�", "鐩爣鍧愭爣锛�" + optionPara.Destination);
@@ -725,8 +727,11 @@
                 if (CurrentState != EnumHelper.DeviceState.DSOpen)
                 {
                     LogAsync(DateTime.Now, "闈炴甯哥姸鎬佸紓甯�", "杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�");
-                    throw new ProcessException("杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�", null);
+
+                    return false;
+                    //throw new ProcessException("杞�" + optionPara.AxisIndex + "璇曞浘鍦ㄩ潪姝e父鐘舵�佽繍鍔�", null);
                 }
+
                 LogAsync(DateTime.Now, "杞�" + optionPara.AxisIndex + "寮�濮嬭繍鍔�", "鐩爣鍧愭爣锛�" + optionPara.Destination);
                 short ret = 0;
                 bool isSuccessSetAxisParam = false;
@@ -783,7 +788,8 @@
                 bool isStop = false;
                 if (option == 1)
                 {
-                    StateChange(EnumHelper.DeviceState.DSExcept);
+                    //StateChange(EnumHelper.DeviceState.DSExcept);
+                    LogAsync(DateTime.Now, "鎬ュ仠鍋滄", "");
                 }
                 var ret = GTSCardAPI.GT_Stop((short)IConfig.CardNum, 1 << (axisNum - 1), option);
                 if (ret != (short)GTSRetCode.GRCRunOK)
diff --git a/src/Bro.Device.Gocator/GocatorConfig.cs b/src/Bro.Device.Gocator/GocatorConfig.cs
index bc3053d..40ec8ba 100644
--- a/src/Bro.Device.Gocator/GocatorConfig.cs
+++ b/src/Bro.Device.Gocator/GocatorConfig.cs
@@ -47,6 +47,16 @@
         [Description("true锛氬紓姝�/琚姩閲囧浘妯″紡  false锛氬悓姝�/涓诲姩閲囧浘妯″紡")]
         [DefaultValue(false)]
         public bool IsAsyncMode { get; set; } = false;
+
+        [Category("鏁版嵁浣嶉厤缃�")]
+        [Description("鍥惧儚鏁版嵁浣嶆暟锛�2浣�/4浣�")]
+        public GocatorDataByteNums ByteNums { get; set; } = GocatorDataByteNums.Byte2;
+    }
+
+    public enum GocatorDataByteNums
+    {
+        Byte2 = 2,
+        Byte4 = 4,
     }
 
     [Device("Gocator", "Gocator婵�鍏夋壂鎻忎华", EnumHelper.DeviceAttributeType.OperationConfig)]
diff --git a/src/Bro.Device.Gocator/GocatorDriver.cs b/src/Bro.Device.Gocator/GocatorDriver.cs
index 0d22a6f..a45de96 100644
--- a/src/Bro.Device.Gocator/GocatorDriver.cs
+++ b/src/Bro.Device.Gocator/GocatorDriver.cs
@@ -94,8 +94,9 @@
                             float zoomFactor = (float)((double)surfaceMsg.YResolution / (double)surfaceMsg.XResolution);
                             int zoomHeight = (int)(zoomFactor * height);
 
-                            IntPtr zoomPtr = Marshal.AllocHGlobal(zoomHeight * (int)width * 2);
+                            //IntPtr zoomPtr = Marshal.AllocHGlobal(zoomHeight * (int)width * 2);
                             //IntPtr zoomPtr = Marshal.AllocHGlobal(zoomHeight * (int)width * 4);
+                            IntPtr zoomPtr = Marshal.AllocHGlobal(zoomHeight * (int)width * (int)IIConfig.ByteNums);
 
                             //娌℃湁鎻掑�硷紝榛樿0
                             //Parallel.For(0, height, h =>
@@ -103,40 +104,45 @@
                             //      CopyMemory((IntPtr)((long)zoomPtr + width * 2 * Math.Floor(h * zoomFactor)), (IntPtr)((long)bufferPointer + width * 2 * h), width * 2);
                             //  });
 
-                            //浣跨敤涓婁竴琛屽師鏈夋暟鎹�
-                            Parallel.For(0, zoomHeight, h =>
+                            if (IIConfig.ByteNums == GocatorDataByteNums.Byte2)
                             {
-                                int originHeightIndex = (int)Math.Floor((double)height * h / (double)zoomHeight);
+                                //浣跨敤涓婁竴琛屽師鏈夋暟鎹�
+                                Parallel.For(0, zoomHeight, h =>
+                                {
+                                    int originHeightIndex = (int)Math.Floor((double)height * h / (double)zoomHeight);
 
-                                CopyMemory((IntPtr)((long)zoomPtr + width * 2 * h), (IntPtr)((long)bufferPointer + width * 2 * originHeightIndex), width * 2);
-                            });
+                                    CopyMemory((IntPtr)((long)zoomPtr + width * 2 * h), (IntPtr)((long)bufferPointer + width * 2 * originHeightIndex), width * 2);
+                                });
+                            }
+                            else
+                            {
+                                //浣跨敤涓婁竴琛屽師鏈夋暟鎹�
+                                Parallel.For(0, zoomHeight, h =>
+                                {
+                                    int originHeightIndex = (int)Math.Floor((double)height * h / (double)zoomHeight);
 
-                            ////浣跨敤涓婁竴琛屽師鏈夋暟鎹�
-                            //Parallel.For(0, zoomHeight, h =>
-                            //{
-                            //    int originHeightIndex = (int)Math.Floor((double)height * h / (double)zoomHeight);
+                                    byte[] rowBuffer = new byte[width * 4];
+                                    Parallel.For(0, width, w =>
+                                    {
+                                        rowBuffer[w * 4 + 2] = Marshal.ReadByte(bufferPointer, (int)(width * 2 * originHeightIndex + w * 2));
+                                        rowBuffer[w * 4 + 3] = Marshal.ReadByte(bufferPointer, (int)(width * 2 * originHeightIndex + w * 2 + 1));
+                                    });
 
-                            //    byte[] rowBuffer = new byte[width * 4];
-                            //    Parallel.For(0, width, w =>
-                            //    {
-                            //        rowBuffer[w * 4 + 2] = Marshal.ReadByte(bufferPointer, (int)(width * 2 * originHeightIndex + w * 2));
-                            //        rowBuffer[w * 4 + 3] = Marshal.ReadByte(bufferPointer, (int)(width * 2 * originHeightIndex + w * 2 + 1));
-                            //    });
-
-                            //    Marshal.Copy(rowBuffer, 0, (IntPtr)((long)zoomPtr + width * 2 * h), rowBuffer.Length);
-                            //});
+                                    Marshal.Copy(rowBuffer, 0, (IntPtr)((long)zoomPtr + width * 2 * h), rowBuffer.Length);
+                                });
+                            }
 
                             if (imgSet != null)
                             {
                                 imgSet.HImage = new HImage();
-                                imgSet.HImage.GenImage1("uint2", (int)width, zoomHeight, zoomPtr);
-
+                                //imgSet.HImage.GenImage1("uint2", (int)width, zoomHeight, zoomPtr);
                                 //imgSet.HImage.GenImage1("int4", (int)width, zoomHeight, zoomPtr);
+                                imgSet.HImage.GenImage1(IIConfig.ByteNums == GocatorDataByteNums.Byte2 ? "uint2" : "int4", (int)width, zoomHeight, zoomPtr);
 
-                                imgSet.HImage_2 = new HImage();
-                                imgSet.HImage_2.GenImage1("uint2", (int)width, zoomHeight, zoomPtr);
-
+                                imgSet.HImage_2 = imgSet.HImage.Clone();
+                                //imgSet.HImage_2.GenImage1("uint2", (int)width, zoomHeight, zoomPtr);
                                 //imgSet.HImage_2.GenImage1("int4", (int)width, zoomHeight, zoomPtr);
+                                //imgSet.HImage_2.GenImage1(IIConfig.ByteNums == GocatorDataByteNums.Byte2 ? "uint2" : "int4", (int)width, zoomHeight, zoomPtr);
 
                                 LaserScanParam para = new LaserScanParam()
                                 {
@@ -289,7 +295,12 @@
 
                 if (!string.IsNullOrWhiteSpace(opConfig.JobName) && _currentJob != opConfig.JobName)
                 {
-                    _currentJob = sensor.DefaultJob = opConfig.JobName;
+                    LogAsync(DateTime.Now, $"{Name}鍒囨崲褰撳墠浠诲姟涓簕opConfig.JobName}", "");
+                    sensor.CopyFile(_currentJob, "_live.job");
+
+                    bool isChanged = false;
+                    sensor.LoadedJob(ref _currentJob, ref isChanged);
+                    LogAsync(DateTime.Now, $"{Name}褰撳墠浠诲姟{_currentJob}", "");
                 }
 
                 sensor.Flush();
@@ -345,18 +356,17 @@
                 _currentExposure = (float)sensor.Setup.GetExposure(GoRole.Main);
             }
 
-            _currentJob = sensor.DefaultJob;
-            if (!string.IsNullOrWhiteSpace(IIConfig.DefaultJob) && _currentJob != IIConfig.DefaultJob)
-            {
-                //_currentJob = sensor.DefaultJob = IIConfig.DefaultJob;
-                string currentJob = IIConfig.DefaultJob;
-                bool isChanged = false;
-                sensor.LoadedJob(ref currentJob, ref isChanged);
+            bool isChanged = false;
+            sensor.LoadedJob(ref _currentJob, ref isChanged);
+            LogAsync(DateTime.Now, $"{Name}褰撳墠浠诲姟{_currentJob}", "");
 
-                if (!isChanged)
-                {
-                    throw new ProcessException($"{Name}鏈垚鍔熷垏鎹㈣嚦浠诲姟{IIConfig.DefaultJob}");
-                }
+            if (!string.IsNullOrWhiteSpace(IIConfig.DefaultJob) && IIConfig.DefaultJob != _currentJob)
+            {
+                sensor.CopyFile(IIConfig.DefaultJob, "_live.job");
+                //_currentJob = IIConfig.DefaultJob;
+
+                sensor.LoadedJob(ref _currentJob, ref isChanged);
+                LogAsync(DateTime.Now, $"{Name}褰撳墠浠诲姟{_currentJob}", "");
             }
 
             sensor.Flush();
diff --git a/src/Bro.Device.HikCamera/Bro.Device.HikCamera.csproj b/src/Bro.Device.HikCamera/Bro.Device.HikCamera.csproj
index fe771d3..d97e16a 100644
--- a/src/Bro.Device.HikCamera/Bro.Device.HikCamera.csproj
+++ b/src/Bro.Device.HikCamera/Bro.Device.HikCamera.csproj
@@ -21,7 +21,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <PlatformTarget>x64</PlatformTarget>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
diff --git a/src/Bro.M071.Process/Bro.M071.Process.csproj b/src/Bro.M071.Process/Bro.M071.Process.csproj
index 4a340fa..d8872b2 100644
--- a/src/Bro.M071.Process/Bro.M071.Process.csproj
+++ b/src/Bro.M071.Process/Bro.M071.Process.csproj
@@ -126,12 +126,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="UI\KeyIndicator.cs" />
     <Compile Include="UI\M071Node.cs" />
-    <Compile Include="UI\M071_DataForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="UI\M071_DataForm.Designer.cs">
-      <DependentUpon>M071_DataForm.cs</DependentUpon>
-    </Compile>
     <Compile Include="UI\M071_MainForm.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -159,9 +153,6 @@
       <AutoGen>True</AutoGen>
       <DependentUpon>Resources.resx</DependentUpon>
     </Compile>
-    <EmbeddedResource Include="UI\M071_DataForm.resx">
-      <DependentUpon>M071_DataForm.cs</DependentUpon>
-    </EmbeddedResource>
     <EmbeddedResource Include="UI\M071_MainForm.resx">
       <DependentUpon>M071_MainForm.cs</DependentUpon>
     </EmbeddedResource>
@@ -194,10 +185,6 @@
     <ProjectReference Include="..\Bro.Common.Model\Bro.Common.Model.csproj">
       <Project>{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}</Project>
       <Name>Bro.Common.Model</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Bro.M071.DBManager\Bro.M071.DBManager.csproj">
-      <Project>{230B0FFF-F6AF-45FE-AAF7-B4B66250DD58}</Project>
-      <Name>Bro.M071.DBManager</Name>
     </ProjectReference>
     <ProjectReference Include="..\Bro.M071.Model\Bro.M071.Model.csproj">
       <Project>{AD645C48-5811-4B1E-B81F-D35D5E6B577F}</Project>
diff --git a/src/Bro.M071.Process/M071Config.cs b/src/Bro.M071.Process/M071Config.cs
index 33cba6e..99f9cdc 100644
--- a/src/Bro.M071.Process/M071Config.cs
+++ b/src/Bro.M071.Process/M071Config.cs
@@ -1,5 +1,6 @@
 锘縰sing Bro.Common.Base;
 using Bro.Common.Helper;
+using Bro.Common.Interface;
 using Bro.Common.Model;
 using Bro.Process;
 using System;
@@ -91,13 +92,13 @@
         //[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
         //public string ResultDataSaveFolder { get; set; } = "";
 
-        [Category("鍥剧墖淇濆瓨閰嶇疆")]
+        [Category("鍗曢敭鍥剧墖淇濆瓨閰嶇疆")]
         [Description("鍗曢敭鍥剧墖淇濆瓨閰嶇疆")]
         [TypeConverter(typeof(ComplexObjectConvert))]
         [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
         public ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
 
-        [Category("鍥剧墖淇濆瓨閰嶇疆")]
+        [Category("鍗曢敭鍥剧墖淇濆瓨閰嶇疆")]
         [Description("鍗曢敭鍥剧墖淇濆瓨鐩綍璺緞")]
         [Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
         public string ImageSaveFolder { get; set; } = "";
@@ -167,9 +168,63 @@
         [DisplayName("澶氭楠岃瘉寮�鍏�")]
         public bool IsDisableMultipleCheckTimes { get; set; }
 
+        [Category("MES璁剧疆")]
+        [Description("閿悕鍜屼笂浼犱唬鐮佹槧灏勫叧绯�")]
+        [DisplayName("閿悕鏄犲皠")]
+        [TypeConverter(typeof(CollectionCountConvert))]
+        [Editor(typeof(ComplexCollectionEditor<KeyCodeMap>), typeof(UITypeEditor))]
+        public List<KeyCodeMap> KeyCodeMappingCollection { get; set; } = new List<KeyCodeMap>();
+
         [Category("澶嶄綅璁剧疆")]
         [Description("澶у浣嶉渶瑕佷俊鍙锋寔缁椂闂达紝澶嶄綅淇″彿鎸佺画瓒呭嚭璇ユ椂闂存墽琛屽ぇ澶嶄綅锛屽崟浣嶏細s")]
         [DisplayName("澶у浣嶆寔缁俊鍙烽暱搴�")]
         public int FullResetRequiredDuration { get; set; } = 3;
     }
+
+    [Device("Demostration", "Demo鎿嶄綔閰嶇疆", EnumHelper.DeviceAttributeType.OperationConfig)]
+    public class DemostrationOperationConfig : OperationConfigBase, IHalconToolPath
+    {
+        [Category("缁勫悎鎿嶄綔閰嶇疆闆嗗悎")]
+        [Description("缁勫悎鎿嶄綔閰嶇疆闆嗗悎")]
+        [TypeConverter(typeof(CollectionCountConvert))]
+        [Editor(typeof(ComplexCollectionEditor<OperationCombination>), typeof(UITypeEditor))]
+        public List<OperationCombination> DemoOperations { get; set; } = new List<OperationCombination>();
+
+        public List<string> GetHalconToolPathList()
+        {
+            return DemoOperations.SelectMany(d => d.GetHalconToolPathList()).ToList();
+        }
+    }
+
+    public class OperationCombination : IComplexDisplay, IHalconToolPath
+    {
+        [Category("杩愬姩鏈烘瀯閰嶇疆")]
+        [Description("杩愬姩鏈烘瀯閰嶇疆")]
+        [TypeConverter(typeof(ComplexObjectConvert))]
+        [Editor(typeof(IOperationConfigByDeviceEditor), typeof(UITypeEditor))]
+        public DeviceOpBind MotionOp { get; set; } = new DeviceOpBind();
+
+        [Category("鐩告満鍜屾搷浣滈厤缃�")]
+        [Description("鐩告満鍜屾搷浣滈厤缃�")]
+        [TypeConverter(typeof(ComplexObjectConvert))]
+        [Editor(typeof(IOperationConfigByDeviceEditor), typeof(UITypeEditor))]
+        public DeviceOpBind CameraOp { get; set; } = new DeviceOpBind();
+
+        public string GetDisplayText()
+        {
+            return MotionOp.GetDisplayText() + "\t" + CameraOp.GetDisplayText();
+        }
+
+        public List<string> GetHalconToolPathList()
+        {
+            if (CameraOp.OpConfig is IHalconToolPath path)
+            {
+                return path.GetHalconToolPathList();
+            }
+            else
+            {
+                return new List<string>();
+            }
+        }
+    }
 }
diff --git a/src/Bro.M071.Process/M071Models.cs b/src/Bro.M071.Process/M071Models.cs
index ed4c138..69113c0 100644
--- a/src/Bro.M071.Process/M071Models.cs
+++ b/src/Bro.M071.Process/M071Models.cs
@@ -52,7 +52,6 @@
         }
     }
 
-
     public class KeyAlgorithem : IComplexDisplay
     {
         [Browsable(false)]
@@ -84,6 +83,10 @@
         [Description("妫�娴嬬畻娉曡矾寰�")]
         [Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
         public string AlgorithemPath { get; set; }
+
+        [Category("涓婁紶NG浠g爜")]
+        [Description("涓婁紶NG浠g爜")]
+        public string NGCode { get; set; }
 
         [Category("鏄剧ず閰嶇疆")]
         [Description("鏄剧ず鍖哄煙澶у皬")]
@@ -509,6 +512,23 @@
         }
     }
 
+    public class KeyCodeMap : IComplexDisplay
+    {
+        [Category("閿悕鏄犲皠閰嶇疆")]
+        [Description("閿悕")]
+        [TypeConverter(typeof(KeyNameDictConverter))]
+        public string Key { get; set; }
+
+        [Category("閿悕鏄犲皠閰嶇疆")]
+        [Description("涓婁紶瀵瑰簲閿唬鐮丆ode")]
+        public string KeyCode { get; set; }
+
+        public string GetDisplayText()
+        {
+            return $"{Key}--{KeyCode}";
+        }
+    }
+
     //public class NoticedDictionary<T1, T2> : Dictionary<T1, T2>, INotifyPropertyChanged
     //{
     //    public event PropertyChangedEventHandler PropertyChanged;
diff --git a/src/Bro.M071.Process/M071Process.cs b/src/Bro.M071.Process/M071Process.cs
index 1de633a..47498b8 100644
--- a/src/Bro.M071.Process/M071Process.cs
+++ b/src/Bro.M071.Process/M071Process.cs
@@ -2,7 +2,7 @@
 using Bro.Common.Helper;
 using Bro.Common.Interface;
 using Bro.Common.Model;
-using Bro.M071.DBManager;
+//using Bro.M071.DBManager;
 using Bro.M071.Model;
 using Bro.M071.Model.Model;
 using Bro.M071.Process.UI;
@@ -361,6 +361,74 @@
 
             return new ProcessResponse();
         }
+
+        [ProcessMethod("Demostration", "CheckBasePlan", "鍩哄噯骞抽潰妫�鏍�", InvokeType.TestInvoke)]
+        public ProcessResponse CheckBasePlan(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice)
+        {
+            if (opConfig is DemostrationOperationConfig config)
+            {
+                config.DemoOperations.ForEach(d =>
+                {
+                    IDevice device = DeviceCollection.FirstOrDefault(u => u.Id == d.MotionOp.Device);
+                    if (device != null)
+                    {
+                        IMotionCard motionDevice = device as IMotionCard;
+
+                        if (motionDevice != null)
+                        {
+                            var response = motionDevice.Run(d.MotionOp.OpConfig);
+                            if (!response.Result)
+                            {
+                                throw new ProcessException($"{device.Name}寮傚父锛寋response.Message}", null, ExceptionLevel.Fatal);
+                            }
+                        }
+                    }
+
+                    CameraBase camera = DeviceCollection.FirstOrDefault(u => u.Id == d.CameraOp.Device) as CameraBase;
+                    if (camera != null)
+                    {
+                        IImageSet set = null;
+                        try
+                        {
+                            set = CollectHImage(camera, d.CameraOp.OpConfig);
+                        }
+                        catch (ProcessException pEx)
+                        {
+                            pEx.Level = ExceptionLevel.Fatal;
+                            throw pEx;
+                        }
+
+                        if (set != null)
+                        {
+                            LaserScanParam scanParam = JsonConvert.DeserializeObject<LaserScanParam>(set.ImageData);
+                            LogAsync(DateTime.Now, $"鎵弿鍙傛暟:{set.ImageData}", "");
+
+                            var tool = GetHalconTool(d.CameraOp.OpConfig, config.MonitorSetId);
+                            if (tool != null)
+                            {
+                                using (tool.InputImageDic["INPUT_Image"] = set.HImage)
+                                {
+                                    tool.InputTupleDic["INPUT_Resolution_Z"] = scanParam.Resolution_Z / 1000000.0;
+
+                                    if (!tool.RunProcedure(out string error))
+                                    {
+                                        LogAsync(DateTime.Now, $"{tool.ProcedureName}鎵ц寮傚父", error);
+                                    }
+                                    else
+                                    {
+                                        var diffX = tool.GetResultTuple("OUTPUT_Result_X").D;
+                                        var diffY = tool.GetResultTuple("OUTPUT_Result_Y").D;
+                                        LogAsync(DateTime.Now, $"妫�娴嬪钩闈紝X鏂瑰悜鏋佸樊锛歿diffX.ToString(_precision)}锛孻鏂瑰悜鏋佸樊锛歿diffY.ToString(_precision)}", "");
+                                    }
+                                }
+                            }
+                        }
+                    }
+                });
+            }
+
+            return new ProcessResponse();
+        }
         #endregion
 
         #region 绉佹湁鏂规硶
@@ -500,44 +568,44 @@
             }
         }
 
-        KeyUnitDataManager keyUnitDataManager = new KeyUnitDataManager();
-        MeasurementUnitResultManager measurementUnitResultManager = new MeasurementUnitResultManager();
-        MeasurementAndKeyDataRelationManager measurementAndKeyDataRelationManager = new MeasurementAndKeyDataRelationManager();
-        ProductionMeasurementRecordsManager productionMeasurementRecordsManager = new ProductionMeasurementRecordsManager();
+        //KeyUnitDataManager keyUnitDataManager = new KeyUnitDataManager();
+        //MeasurementUnitResultManager measurementUnitResultManager = new MeasurementUnitResultManager();
+        //MeasurementAndKeyDataRelationManager measurementAndKeyDataRelationManager = new MeasurementAndKeyDataRelationManager();
+        //ProductionMeasurementRecordsManager productionMeasurementRecordsManager = new ProductionMeasurementRecordsManager();
 
         static object dataSaveLock = new object();
 
-        private async void SaveProductionData(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet)
-        {
-            await Task.Run(() =>
-            {
-                try
-                {
-                    lock (dataSaveLock)
-                    {
-                        // 鑾峰彇 浜у搧鏁版嵁 骞朵繚瀛�
-                        var productionMeasurementRecords = measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord;
-                        productionMeasurementRecordsManager.CreateModel(productionMeasurementRecords);
+        //private async void SaveProductionData(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet)
+        //{
+        //    await Task.Run(() =>
+        //    {
+        //        try
+        //        {
+        //            lock (dataSaveLock)
+        //            {
+        //                // 鑾峰彇 浜у搧鏁版嵁 骞朵繚瀛�
+        //                var productionMeasurementRecords = measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord;
+        //                productionMeasurementRecordsManager.CreateModel(productionMeasurementRecords);
 
-                        // 鑾峰彇 鍘熷鏁版嵁 骞朵繚瀛�
-                        var keyUnitDatas = measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList;
-                        keyUnitDataManager.BatchAddKeyUnitData(keyUnitDatas);
+        //                // 鑾峰彇 鍘熷鏁版嵁 骞朵繚瀛�
+        //                var keyUnitDatas = measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList;
+        //                keyUnitDataManager.BatchAddKeyUnitData(keyUnitDatas);
 
-                        // 鑾峰彇 妫�娴嬬粨鏋滄暟鎹� 骞朵繚瀛�
-                        var measurementUnitResults = measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList;
-                        measurementUnitResultManager.BatchAddMeasurementUnitResult(measurementUnitResults);
+        //                // 鑾峰彇 妫�娴嬬粨鏋滄暟鎹� 骞朵繚瀛�
+        //                var measurementUnitResults = measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList;
+        //                measurementUnitResultManager.BatchAddMeasurementUnitResult(measurementUnitResults);
 
-                        // 鑾峰彇 鍏崇郴鏁版嵁骞朵繚瀛�
-                        var measurementAndKeyDataRelationList = measurementUnitResultAndKeyUnitDataSet.MeasurementAndKeyDataRelationList;
-                        measurementAndKeyDataRelationManager.BatchAddMeasurementAndKeyDataRelation(measurementAndKeyDataRelationList);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    LogAsync(DateTime.Now, "鏁版嵁淇濆瓨寮傚父", ex.GetExceptionMessage());
-                }
-            });
-        }
+        //                // 鑾峰彇 鍏崇郴鏁版嵁骞朵繚瀛�
+        //                var measurementAndKeyDataRelationList = measurementUnitResultAndKeyUnitDataSet.MeasurementAndKeyDataRelationList;
+        //                measurementAndKeyDataRelationManager.BatchAddMeasurementAndKeyDataRelation(measurementAndKeyDataRelationList);
+        //            }
+        //        }
+        //        catch (Exception ex)
+        //        {
+        //            LogAsync(DateTime.Now, "鏁版嵁淇濆瓨寮傚父", ex.GetExceptionMessage());
+        //        }
+        //    });
+        //}
 
         private ProductionMeasurementUnitResultAndKeyUnitDataSet GetMeasurementUnitResultAndKeyUnitData(ProductionMeasurement pData)
         {
@@ -620,49 +688,49 @@
             return measurementUnitResultAndKeyUnitDataSet;
         }
 
-        private async void ExportProductionExcel(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet)
-        {
-            if (!Config.IsCSVOutputEnabled)
-                return;
+        //private async void ExportProductionExcel(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet)
+        //{
+        //    if (!Config.IsCSVOutputEnabled)
+        //        return;
 
-            await Task.Run(() =>
-            {
-                ExcelExportSet excelExportDto = new ExcelExportSet();
-                excelExportDto.Worksheets = new List<string>() { "鍘熷鏁版嵁", "妫�娴嬬粨鏋�" };
-                var keyUnitColumns = new Dictionary<string, string>()
-                {
-                    {"ProductionBarcode", "浜у搧鏉$爜"},
-                    {"Key", "閿�"},
-                    {"MeasurementItem", "妫�娴嬮」"},
-                    {"ItemValue", "妫�娴嬪��"}
-                };
-                var measurementUnitResultColumns = new Dictionary<string, string>()
-                {
-                    {"ProductionBarcode", "浜у搧鏉$爜"},
-                    {"MeasurementName", "妫�娴嬪悕绉�"},
-                    {"MeasurementType", "妫�娴嬬被鍨�"},
-                    {"MeasurementValue", "妫�娴嬪��"},
-                    {"MeasurementResult", "妫�娴嬬粨鏋�"},
-                };
-                excelExportDto.WorksheetColumns[excelExportDto.Worksheets[0]] = keyUnitColumns;
-                excelExportDto.WorksheetColumns[excelExportDto.Worksheets[1]] = measurementUnitResultColumns;
+        //    await Task.Run(() =>
+        //    {
+        //        ExcelExportSet excelExportDto = new ExcelExportSet();
+        //        excelExportDto.Worksheets = new List<string>() { "鍘熷鏁版嵁", "妫�娴嬬粨鏋�" };
+        //        var keyUnitColumns = new Dictionary<string, string>()
+        //        {
+        //            {"ProductionBarcode", "浜у搧鏉$爜"},
+        //            {"Key", "閿�"},
+        //            {"MeasurementItem", "妫�娴嬮」"},
+        //            {"ItemValue", "妫�娴嬪��"}
+        //        };
+        //        var measurementUnitResultColumns = new Dictionary<string, string>()
+        //        {
+        //            {"ProductionBarcode", "浜у搧鏉$爜"},
+        //            {"MeasurementName", "妫�娴嬪悕绉�"},
+        //            {"MeasurementType", "妫�娴嬬被鍨�"},
+        //            {"MeasurementValue", "妫�娴嬪��"},
+        //            {"MeasurementResult", "妫�娴嬬粨鏋�"},
+        //        };
+        //        excelExportDto.WorksheetColumns[excelExportDto.Worksheets[0]] = keyUnitColumns;
+        //        excelExportDto.WorksheetColumns[excelExportDto.Worksheets[1]] = measurementUnitResultColumns;
 
-                excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[0]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList, keyUnitColumns);
-                excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[1]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList, measurementUnitResultColumns); ;
+        //        excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[0]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList, keyUnitColumns);
+        //        excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[1]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList, measurementUnitResultColumns); ;
 
-                if (!Directory.Exists(Config.LogPath))
-                {
-                    Directory.CreateDirectory(Config.LogPath);
-                }
-                var fileName = Path.Combine(Config.LogPath, $"ProductionData_{DateTime.Now.ToString("yyyyMMdd")}.xlsx");
+        //        if (!Directory.Exists(Config.LogPath))
+        //        {
+        //            Directory.CreateDirectory(Config.LogPath);
+        //        }
+        //        var fileName = Path.Combine(Config.LogPath, $"ProductionData_{DateTime.Now.ToString("yyyyMMdd")}.xlsx");
 
-                byte[] filecontent = ExcelExportHelper.CreateOrAppendExcel(excelExportDto, fileName);
-                FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
-                fs.Write(filecontent, 0, filecontent.Length);
-                fs.Flush();
-                fs.Close();
-            });
-        }
+        //        byte[] filecontent = ExcelExportHelper.CreateOrAppendExcel(excelExportDto, fileName);
+        //        FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
+        //        fs.Write(filecontent, 0, filecontent.Length);
+        //        fs.Flush();
+        //        fs.Close();
+        //    });
+        //}
 
         static object excelExportLock = new object();
         private async void ExportProductionInColumns(ProductionMeasurementUnitResultAndKeyUnitDataSet exportData)
@@ -815,7 +883,7 @@
                         #endregion
 
                         #region Slant
-                        var slantMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "Slant").ToList();
+                        var slantMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType.StartsWith("Slant")).ToList();
                         if (slantMeasures.Count > 0)
                         {
                             int slantStartCol = slantSheet.Dimension.Columns;
@@ -854,7 +922,7 @@
 
                         #region Alignment
                         {
-                            var alignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "Alignment").ToList();
+                            var alignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType.StartsWith("Alignment")).ToList();
                             if (alignmentMeasures.Count > 0)
                             {
                                 List<string> keysList = new List<string>();
@@ -913,7 +981,7 @@
 
                         #region RowAlignment
                         {
-                            var rowAlignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType == "RowAlignment").ToList();
+                            var rowAlignmentMeasures = exportData.MeasurementUnitResultList.Where(u => u.MeasurementType.StartsWith("RowAlignment")).ToList();
                             if (rowAlignmentMeasures.Count > 0)
                             {
                                 List<string> keysList = new List<string>();
diff --git a/src/Bro.M071.Process/M071Process_MES.cs b/src/Bro.M071.Process/M071Process_MES.cs
index a5277b3..7f63e68 100644
--- a/src/Bro.M071.Process/M071Process_MES.cs
+++ b/src/Bro.M071.Process/M071Process_MES.cs
@@ -82,14 +82,14 @@
         {
             get
             {
-                if (incomingCheckMethod == null)
+                if (dataUploadMethod == null)
                 {
-                    incomingCheckMethod = InitialMESWebServiceMethod(DataUploadMethodName, out DataUploadObj);
+                    dataUploadMethod = InitialMESWebServiceMethod(DataUploadMethodName, out DataUploadObj);
                 }
 
-                return incomingCheckMethod;
+                return dataUploadMethod;
             }
-            set => incomingCheckMethod = value;
+            set => dataUploadMethod = value;
         }
 
         private MethodInfo InitialMESWebServiceMethod(string methodName, out object invokeClass)
@@ -138,7 +138,7 @@
             //string paraStr = JsonConvert.SerializeObject(paras);
             //LogAsync(DateTime.Now, $"MES鍏ユ枡妫�娴� {url}", paraStr);
 
-            IncomingCheckMethod = InitialMESWebServiceMethod(IncomingCheckMethodName, out IncomingCheckObj);
+            //IncomingCheckMethod = InitialMESWebServiceMethod(IncomingCheckMethodName, out IncomingCheckObj);
 
             Stopwatch sw = new Stopwatch();
             sw.Start();
@@ -178,7 +178,7 @@
             //string paraStr = JsonConvert.SerializeObject(paras);
             //LogAsync(DateTime.Now, $"MES鏁版嵁涓婁紶 {url}", paraStr);
 
-            DataUploadMethod = InitialMESWebServiceMethod(DataUploadMethodName, out DataUploadObj);
+            //DataUploadMethod = InitialMESWebServiceMethod(DataUploadMethodName, out DataUploadObj);
 
             Stopwatch sw = new Stopwatch();
             sw.Start();
@@ -195,7 +195,8 @@
                 pMeasure.PResult == "OK" ? "PASS" : "FAIL",
                 Config.LineCode,
                 GetMESSlantData(pMeasure),
-                GetMESAlignmentData(pMeasure)
+                GetMESAlignmentData(pMeasure),
+                GetNGKeys(pMeasure)
             };
 
             //LogAsync(DateTime.Now, $"{barcode}浜у搧妫�娴嬫暟鎹笂浼�", JsonConvert.SerializeObject(paras));
@@ -210,12 +211,59 @@
 
         private string GetMESAlignmentData(ProductionMeasurement pMeasure)
         {
-            return string.Join(",", pMeasure.Measurements.Where(u => u.MeasureType == "Alignment").Select(u => $"{u.Name}:{u.Spec.ActualValue.Value.ToString(_precision)}"));
+            return string.Join(",", pMeasure.Measurements.Where(u => u.MeasureType.StartsWith("Alignment")).Select(u => $"{u.Name}:{u.Spec.ActualValue.Value.ToString(_precision)}"));
         }
 
         private string GetMESSlantData(ProductionMeasurement pMeasure)
         {
-            return string.Join(",", pMeasure.Measurements.Where(u => u.MeasureType == "Slant").Select(u => $"{u.Name}:{u.Spec.ActualValue.Value.ToString(_precision)}"));
+            return string.Join(",", pMeasure.Measurements.Where(u => u.MeasureType.StartsWith("Slant")).Select(u => $"{u.Name}:{u.Spec.ActualValue.Value.ToString(_precision)}"));
+        }
+
+        private string GetNGKeys(ProductionMeasurement pMeasure)
+        {
+            string ngCodes = "";
+            Dictionary<string, List<string>> ngCodeDict = new Dictionary<string, List<string>>();
+
+            var ngList = pMeasure.Measurements.Where(m => m.Spec.MeasureResult != true).ToList();
+            if (ngList.Count == 0)
+                return "";
+
+            ngList.GroupBy(m => m.MeasureType).ToList().ForEach(g =>
+                  {
+                      var mType = Config.MeasureTypeCollection.FirstOrDefault(u => u.Code == g.Key);
+                      if (mType != null)
+                      {
+                          if (!ngCodeDict.ContainsKey(mType.NGCode))
+                          {
+                              ngCodeDict[mType.NGCode] = new List<string>();
+                          }
+
+                          g.ToList().ForEach(k =>
+                          {
+                              k.KeyUnitCollection.Select(kk => kk.Key).ToList().ForEach(key =>
+                              {
+                                  string uploadKeyCode = key;
+                                  var keyCodeMap = Config.KeyCodeMappingCollection.FirstOrDefault(kcm => kcm.Key == key);
+                                  if (keyCodeMap != null)
+                                  {
+                                      uploadKeyCode = keyCodeMap.KeyCode;
+                                  }
+
+                                  if (!ngCodeDict[mType.NGCode].Contains(uploadKeyCode))
+                                  {
+                                      ngCodeDict[mType.NGCode].Add(uploadKeyCode);
+                                  }
+                              });
+                          });
+                      }
+                  });
+
+            if (ngCodeDict.Count > 0)
+            {
+                ngCodes = string.Join(";", ngCodeDict.ToList().Select(u => $"{u.Key}:{string.Join(",", u.Value)}"));
+            }
+
+            return ngCodes;
         }
     }
 
diff --git a/src/Bro.M071.Process/UI/KeyIndicator.cs b/src/Bro.M071.Process/UI/KeyIndicator.cs
index 91caa8b..6a0b128 100644
--- a/src/Bro.M071.Process/UI/KeyIndicator.cs
+++ b/src/Bro.M071.Process/UI/KeyIndicator.cs
@@ -157,7 +157,7 @@
             return Math.Abs(p.X - (DisplayRect.X + DisplayRect.Width)) < (DisplayRect.Width / 3) && Math.Abs(p.Y - (DisplayRect.Y + DisplayRect.Height)) < (DisplayRect.Height / 3);
         }
 
-        int x, y = 0;
+        //int x, y = 0;
         public override void StretchBottom(Point p)
         {
             if (p.Y > DisplayRect.Y)
diff --git a/src/Bro.M071.Process/UI/M071_MainForm.cs b/src/Bro.M071.Process/UI/M071_MainForm.cs
index 4893258..8ef45d1 100644
--- a/src/Bro.M071.Process/UI/M071_MainForm.cs
+++ b/src/Bro.M071.Process/UI/M071_MainForm.cs
@@ -317,6 +317,10 @@
             {
                 _barcode += keyStr.Substring(1).ToUpper();
             }
+            else if (keyStr.StartsWith("NumPad"))
+            {
+                _barcode += keyStr.Replace("NumPad", "");
+            }
 
             if (e.KeyValue == 13)
             {
diff --git a/src/Bro.Process/ProcessControl.cs b/src/Bro.Process/ProcessControl.cs
index 359e771..2f31a10 100644
--- a/src/Bro.Process/ProcessControl.cs
+++ b/src/Bro.Process/ProcessControl.cs
@@ -21,7 +21,7 @@
 using System.Threading.Tasks;
 using static Bro.Common.Helper.EnumHelper;
 
-namespace Bro.Process  
+namespace Bro.Process
 {
     [Process("", DeviceAttributeType.Device)]
     public partial class ProcessControl : IProcess
@@ -470,14 +470,14 @@
         /// <param name="config">鎿嶄綔閰嶇疆锛岀敤鏉ョ‘璁ょ洃鍚潵婧愬拰绠楁硶璺緞</param>
         /// <param name="algorithemPath">绠楁硶璺緞锛岄粯璁ゆ槸閰嶇疆涓殑绗竴涓畻娉曡矾寰�</param>
         /// <returns>Halcon绠楁硶</returns>
-        protected HDevEngineTool GetHalconTool(IOperationConfig config, string algorithemPath = "")
+        protected HDevEngineTool GetHalconTool(IOperationConfig config, string monitorSetId = "", string algorithemPath = "")
         {
             if (string.IsNullOrWhiteSpace(algorithemPath))
             {
                 algorithemPath = (config as IHalconToolPath)?.GetHalconToolPathList()[0];
             }
 
-            string key = config.MonitorSetId + "|" + algorithemPath;
+            string key = (string.IsNullOrWhiteSpace(monitorSetId) ? config.MonitorSetId : monitorSetId) + "|" + algorithemPath;
             if (_halconToolDict.ContainsKey(key))
             {
                 return _halconToolDict[key];
@@ -631,7 +631,7 @@
         #endregion
 
         #region 鍥惧儚澶勭悊
-        protected IImageSet CollectHImage(CameraBase camera, IOperationConfig opConfig, [CallerMemberName]string methodCode = "")
+        protected IImageSet CollectHImage(CameraBase camera, IOperationConfig opConfig, [CallerMemberName] string methodCode = "")
         {
             IImageSet set = null;
 
diff --git a/src/ExcelTest/ExcelTest.csproj b/src/ExcelTest/ExcelTest.csproj
index 2ab571f..188364b 100644
--- a/src/ExcelTest/ExcelTest.csproj
+++ b/src/ExcelTest/ExcelTest.csproj
@@ -80,10 +80,6 @@
     <None Include="App.config" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\Bro.M071.DBManager\Bro.M071.DBManager.csproj">
-      <Project>{230B0FFF-F6AF-45FE-AAF7-B4B66250DD58}</Project>
-      <Name>Bro.M071.DBManager</Name>
-    </ProjectReference>
     <ProjectReference Include="..\Bro.M071.Model\Bro.M071.Model.csproj">
       <Project>{AD645C48-5811-4B1E-B81F-D35D5E6B577F}</Project>
       <Name>Bro.M071.Model</Name>

--
Gitblit v1.8.0