领胜LDS 键盘AOI检测项目
src/Bro.Process/ProcessControl.cs
@@ -45,7 +45,6 @@
        #region Event
        public event Action<string, Bitmap, string> OnBitmapOutput;
        //public event Action<string, object> OnObjectOutput;
        public Action<DateTime, Exception> OnExceptionOccured { get; set; }
        public event Action<DeviceState> OnProcessStateChanged;
        public event Action<DateTime, string, string> OnLog;
@@ -209,10 +208,17 @@
                    d.OnLog -= OnDeviceLog;
                    d.OnLog += OnDeviceLog;
                    d.OnExceptionOccured = OnDeviceExceptionRaised;
                    d.StateChange(DeviceState.DSInit);
                    d.StateChange(DeviceState.DSOpen);
                }
            });
        }
        private void OnDeviceExceptionRaised(DateTime dt, Exception ex)
        {
            LogAsync(dt, "设备异常", ex.GetExceptionMessage());
        }
        #endregion
@@ -342,6 +348,37 @@
            }
        }
        public void CreateNewConfig(IProcessConfig config, string newProductionCode)
        {
            try
            {
                if (config == null)
                    throw new ProcessException("保存的配置信息不能为空");
                string newConfigPath = Path.Combine(Path.GetDirectoryName(_configPath), $"Config_{newProductionCode}.json");
                if (File.Exists(newConfigPath))
                {
                    throw new ProcessException($"{newProductionCode}配置文件已经存在");
                }
                //生成config.json
                string newConfig = JsonConvert.SerializeObject(config, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });
                using (StreamWriter writer = new StreamWriter(newConfigPath, false, System.Text.Encoding.UTF8))
                {
                    writer.Write(newConfig);
                    writer.Flush();
                    writer.Close();
                }
                //添加到Setting.json
                SettingHelper.AddNewProductionCode(newProductionCode);
            }
            catch (Exception ex)
            {
                throw new ProcessException(ex.Message, null);
            }
        }
        private void SaveBackupConfig()
        {
            string backPath = Path.GetDirectoryName(_configPath);
@@ -398,7 +435,7 @@
        #endregion
        #region Halcon算子设置
        private void InitialHalconTool()
        protected virtual void InitialHalconTool()
        {
            foreach (HDevEngineTool tool in _halconToolDict.Values)
            {
@@ -413,20 +450,25 @@
                {
                    toolPath.GetHalconToolPathList().ForEach(path =>
                    {
                        if (!string.IsNullOrWhiteSpace(path))
                        {
                            string directoryPath = Path.GetDirectoryName(path);
                            string fileName = Path.GetFileNameWithoutExtension(path);
                            HDevEngineTool tool = new HDevEngineTool(directoryPath);
                            tool.LoadProcedure(fileName);
                            //使用“|”作为间隔符
                            _halconToolDict[monitorSet.Id + "|" + path] = tool;
                        }
                        LoadHalconTool(path, monitorSet.Id);
                    });
                }
            });
        }
        protected void LoadHalconTool(string algorithemPath, string prefix)
        {
            if (!string.IsNullOrWhiteSpace(algorithemPath))
            {
                string directoryPath = Path.GetDirectoryName(algorithemPath);
                string fileName = Path.GetFileNameWithoutExtension(algorithemPath);
                HDevEngineTool tool = new HDevEngineTool(directoryPath);
                tool.LoadProcedure(fileName);
                //使用“|”作为间隔符
                _halconToolDict[prefix + "|" + algorithemPath] = tool;
            }
        }
        /// <summary>
@@ -435,14 +477,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];
@@ -479,7 +521,7 @@
        #endregion
        #region IMonitor监听
        protected virtual void OnMonitorInvoke(DateTime dt, string deviceId, IDevice sourceDevice, MonitorSet monitorSet)
        protected virtual void OnMonitorInvoke(DateTime dt, string deviceId, IDevice sourceDevice, IMonitorSet monitorSet)
        {
            string methodCode = monitorSet.MethodCode;
@@ -490,11 +532,14 @@
                return;
            }
            if (!ProcessInvokePreCheck())
                return;
            IOperationConfig config = monitorSet.OpConfig;
            object res = null;
            int reTryTimes = config.ReTryTimes;
            IDevice device = DeviceCollection.FirstOrDefault(u => u.Id == deviceId);
            LogAsync(DateTime.Now, $"{device.Name}调用{methodCode}开始", "");
            LogAsync(DateTime.Now, $"{device?.Name}调用{methodCode}开始", "");
            Stopwatch sw = new Stopwatch();
            sw.Start();
@@ -548,6 +593,8 @@
                        }
                        LogAsync(DateTime.Now, methodCode + "异常信息", ex.GetExceptionMessage());
                        ExceptionRaisedInMonitor(ex);
                    }
                }
@@ -568,15 +615,32 @@
            #endregion
            sw.Stop();
            LogAsync(DateTime.Now, $"{device.Name}调用{methodCode}完成,耗时{sw.ElapsedMilliseconds}ms", "");
            TimeRecordCSV(DateTime.Now, device.Name, $"{methodCode}调用完成", (int)sw.ElapsedMilliseconds);
            LogAsync(DateTime.Now, $"{device?.Name}调用{methodCode}完成,耗时{sw.ElapsedMilliseconds}ms", "");
            TimeRecordCSV(DateTime.Now, device?.Name, $"{methodCode}调用完成", (int)sw.ElapsedMilliseconds);
        }
        /// <summary>
        /// 流程执行的预检查
        /// </summary>
        /// <returns></returns>
        public virtual bool ProcessInvokePreCheck()
        {
            return true;
        }
        /// <summary>
        /// 监听流程中异常抛出 在具体业务中具体处理
        /// </summary>
        /// <param name="ex">监听流程中异常对象</param>
        public virtual void ExceptionRaisedInMonitor(Exception ex)
        {
        }
        #endregion
        #region 图像处理
        protected HImage CollectHImage(CameraBase camera, IOperationConfig opConfig, out string imgSetId, [CallerMemberName]string methodCode = "")
        protected IImageSet CollectHImage(CameraBase camera, IOperationConfig opConfig, [CallerMemberName] string methodCode = "")
        {
            ImageSet set = null;
            IImageSet set = null;
            if (IConfig.IsImageOffline)
            {
@@ -623,8 +687,7 @@
                TimeRecordCSV(DateTime.Now, camera.Name, methodCode + "采图", (int)sw.ElapsedMilliseconds);
            }
            imgSetId = set.Id;
            return set.HImage;
            return set;
        }
        protected async void CameraUpdateImage(CameraBase camera, Bitmap image, string setId)
@@ -637,9 +700,9 @@
        #endregion
        #region 报警和DownTime
        ObservableCollection<WarningSet> _warningRemains = new ObservableCollection<WarningSet>();
        ObservableCollection<IWarningSet> _warningRemains = new ObservableCollection<IWarningSet>();
        protected virtual void OnMonitorAlarm(DateTime dt, IDevice device, WarningSet warning)
        protected virtual void OnMonitorAlarm(DateTime dt, IDevice device, IWarningSet warning)
        {
            if (warning.CurrentStatus)
            {
@@ -668,6 +731,14 @@
            OnAlarmUpdate?.BeginInvoke(alarmMsg, null, null);
        }
        public async virtual void RaisedAlarm(string alarmMsg)
        {
            await Task.Run(() =>
            {
                OnAlarmUpdate?.Invoke(alarmMsg);
            });
        }
        #endregion
        #region ILogger