patrick
2019-12-10 1c4426810c71eead57084be8a18ade8d314dd8c4
src/A032.Process/ProcessControl.cs
@@ -3,9 +3,7 @@
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using Bro.Common.PubSub;
using Bro.Common.UI;
using Bro.Device.AuboRobot;
using Bro.Device.OmronFins;
using Bro.Device.SeerAGV;
@@ -14,18 +12,14 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;
using static Bro.Common.Helper.EnumHelper;
@@ -40,7 +34,7 @@
        {
            #region AutoFac注册
            builder.RegisterInstance<ProcessConfig>(StationConfig as ProcessConfig);
            builder.RegisterInstance<List<IDevice>>(GetDeviceList());
            builder.RegisterInstance<List<IDevice>>(DeviceList);
            builder.RegisterInstance<List<ProcessMethodAttribute>>(CollectProcessMethods());
            if (isBuild)
@@ -125,6 +119,8 @@
        Dictionary<string, SeerAGVDriver> AGVDict = new Dictionary<string, SeerAGVDriver>();
        Dictionary<string, CameraBase> CameraDict = new Dictionary<string, CameraBase>();
        public List<IDevice> DeviceList { get; set; } = new List<IDevice>();
        private ProcessConfig Config { get => StationConfig as ProcessConfig; }
        string _configBackupStr = "";
@@ -152,6 +148,11 @@
            if (ProcessState == DeviceState.DSClose)
                return;
            List<string> currentTaskIds = Config.AGVBindCollection.Select(u => u.CurrentTaskId).Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
            TrayTaskCollection.RemoveAll(t => !currentTaskIds.Contains(t.TaskId));
            _bindTaskDoneHandleDict.Values.ToList().ForEach(h => h.WaitOne());
            CloseDevice(PLCDict.Values.ToList());
            CloseDevice(RobotDict.Values.ToList());
            CloseDevice(AGVDict.Values.ToList());
@@ -168,6 +169,7 @@
                return;
            InitialProcessMethods();
            TrayTaskCollection.OnItemChangedWithItemInfo = OnTaskListChanged;
            OpenDevices(RobotDict.Values.ToList());
            OpenDevices(AGVDict.Values.ToList());
@@ -177,14 +179,15 @@
            OpenDevices(PLCDict.Values.ToList());
            //加载AGVUnit状态事件
            Config.AGVBindCollection.ForEach(b =>
            {
                b.OnUnitStateChanged = OnUnitStateChanged;
                _bindTaskDoneHandleDict[b.Id] = new AutoResetEvent(true);
            });
            ProcessState = DeviceState.DSOpen;
            //QueryRobotIO();
            //Task.Run(() =>
            //{
            //    //PLCMonitor();
            //});
            LogAsync(DateTime.Now, "Process Opened", "");
        }
@@ -291,27 +294,31 @@
            #region 个别配置的特别处理
            #endregion
            _warningRemains.CollectionChanged -= _warningRemains_CollectionChanged;
            _warningRemains.CollectionChanged += _warningRemains_CollectionChanged;
            WarningRemains.CollectionChanged -= _warningRemains_CollectionChanged;
            WarningRemains.CollectionChanged += _warningRemains_CollectionChanged;
            #region 设备初始化
            DeviceList = new List<IDevice>();
            InitialPLCs();
            InitialAGVs();
            InitialRobots();
            InitialCameras();
            InitialAGVBindUnit();
            InitialMachineTrayNums();
            //InitialMachineTrayNums();
            #endregion
            AutoFacRegister();
            LogAsync(DateTime.Now, "Process Initialized", "");
        }
        private void InitialMachineTrayNums()
        {
            machineEmptyTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.UnloadEmptyTray).ToDictionary(p => p.PositionNo, p => 0);
        //private void InitialMachineTrayNums()
        //{
        //    machineEmptyTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.UnloadEmptyTray).ToDictionary(p => p.PositionNo, p => 0);
            machineFullTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.LoadFullTray).ToDictionary(p => p.PositionNo, p => 0);
        }
        //    machineFullTrayDict = Config.PositionCollection.Where(u => u.Description == PathPositionDefinition.LoadFullTray).ToDictionary(p => p.PositionNo, p => 0);
        //}
        private void InitialAGVBindUnit()
        {
@@ -343,6 +350,8 @@
                CameraBase camera = CameraHelper.GetCameraInstance(c.DriverType);
                camera.InitialConfig = c;
                CameraDict[camera.InitialConfig.ID] = camera;
                DeviceList.Add(camera);
            });
        }
@@ -359,6 +368,8 @@
                plc.OnMonitorAlarm += OnMonitorAlarm;
                plc.OnMonitorInvoke += OnMonitorInvoke;
                DeviceList.Add(plc);
            });
        }
@@ -370,6 +381,8 @@
                robot.InitialConfig = c;
                RobotDict[robot.InitialConfig.ID] = robot;
                robot.OnLog = OnDeviceLog;
                robot.OnMsgReceived = OnRobotMsgReceived;
                robot.OnMonitorAlarm -= OnMonitorAlarm;
@@ -377,6 +390,8 @@
                robot.OnMonitorAlarm += OnMonitorAlarm;
                robot.OnMonitorInvoke += OnMonitorInvoke;
                DeviceList.Add(robot);
            });
        }
@@ -388,9 +403,18 @@
                agv.InitialConfig = c;
                AGVDict[agv.InitialConfig.ID] = agv;
                agv.OnMonitorAlarm -= OnMonitorAlarm;
                agv.OnMonitorInvoke -= OnMonitorInvoke;
                agv.OnMonitorAlarm += OnMonitorAlarm;
                agv.OnMonitorInvoke += OnMonitorInvoke;
                agv.OnLog = OnDeviceLog;
                agv.OnAGVPositoinChanged = OnAGVPositionChanged;
                agv.OnAGVTaskStatusChanged = OnAGVTaskStatusChanged;
                agv.OnAGVBatteryLvlChanged = OnAGVBatterLvlChanged;
                agv.OnAGVBatteryLvlChanged = OnAGVBatteryLvlChanged;
                DeviceList.Add(agv);
            });
        }
@@ -445,7 +469,7 @@
            ProcessConfig pConfig = config as ProcessConfig;
            if (pConfig == null)
                throw new ProcessException("目前只支持ProcessConfig类型的非空内容保存", null);
                throw new ProcessException("目前只支持ProcessConfig类型的非空内容保存");
            string newConfig = JsonConvert.SerializeObject(pConfig, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
            using (StreamWriter writer = new StreamWriter(CONFIG_PATH, false, System.Text.Encoding.UTF8))
@@ -502,84 +526,49 @@
                if (attr != null)
                {
                    _processMethodDict[attr.MethodCode] = m;
                    #region 初始化HalconTool 根据processMethod的特性来配置
                    //if (attr.DeviceType.EndsWith("Camera"))
                    //{
                    //    if (StationConfig.ProcessOpConfigDict.Keys.Contains(attr.MethodCode))
                    //    {
                    //        var opConfig = StationConfig.ProcessOpConfigDict[attr.MethodCode] as HalconRelatedCameraOprerationConfigBase;
                    //        if (opConfig != null)
                    //        {
                    //            if (!string.IsNullOrWhiteSpace(opConfig.AlgorithemPath))
                    //            {
                    //                string directoryPath = Path.GetDirectoryName(opConfig.AlgorithemPath);
                    //                string fileName = Path.GetFileNameWithoutExtension(opConfig.AlgorithemPath);
                    //                HDevEngineTool tool = new HDevEngineTool(directoryPath);
                    //                tool.LoadProcedure(fileName);
                    //                _halconToolDict[attr.MethodCode] = tool;
                    //            }
                    //        }
                    //    }
                    //}
                    #endregion
                }
            });
            #region 初始化HalconTool 根据配置的接口类型来配置
            _halconToolDict = new Dictionary<string, HDevEngineTool>();
            Config.PLCConfigCollection.SelectMany(plcConfig => plcConfig.MonitorSetCollection).Select(ms => ms.OpConfig).ToList().ForEach(c =>
            {
                InitialHalconTool(c as IHalconToolPath);
            });
            Config.VisionConfigCollection.ForEach(c =>
            {
                InitialHalconTool(c as IHalconToolPath);
            });
            Config.ProcessOpConfigDict.Values.ToList().ForEach(c =>
            {
                InitialHalconTool(c as IHalconToolPath);
            });
            InitialHalconTool();
            #endregion
        }
        private void InitialHalconTool(IHalconToolPath toolPath)
        private void InitialHalconTool()
        {
            //IHalconToolPath toolPath = c as IHalconToolPath;
            if (toolPath != null)
            foreach (HDevEngineTool tool in _halconToolDict.Values)
            {
                toolPath.GetHalconToolPathList().ForEach(path =>
                {
                    if (!string.IsNullOrWhiteSpace(path) && !_halconToolDict.ContainsKey(path))
                    {
                        string directoryPath = Path.GetDirectoryName(path);
                        string fileName = Path.GetFileNameWithoutExtension(path);
                        HDevEngineTool tool = new HDevEngineTool(directoryPath);
                        tool.LoadProcedure(fileName);
                        _halconToolDict[path] = tool;
                    }
                });
                tool?.Dispose();
            }
            _halconToolDict = new Dictionary<string, HDevEngineTool>();
            Config.GetHalconToolPathList().ForEach(path =>
            {
                if (!string.IsNullOrWhiteSpace(path) && !_halconToolDict.ContainsKey(path))
                {
                    string directoryPath = Path.GetDirectoryName(path);
                    string fileName = Path.GetFileNameWithoutExtension(path);
                    HDevEngineTool tool = new HDevEngineTool(directoryPath);
                    tool.LoadProcedure(fileName);
                    _halconToolDict[path] = tool;
                }
            });
        }
        public List<IDevice> GetDeviceList()
        {
            List<IDevice> list = new List<IDevice>();
        //public List<IDevice> GetDeviceList()
        //{
        //    List<IDevice> list = new List<IDevice>();
            list.AddRange(PLCDict.Values);
            list.AddRange(RobotDict.Values);
            list.AddRange(AGVDict.Values);
            list.AddRange(CameraDict.Values);
        //    list.AddRange(PLCDict.Values);
        //    list.AddRange(RobotDict.Values);
        //    list.AddRange(AGVDict.Values);
        //    list.AddRange(CameraDict.Values);
            return list;
        }
        //    return list;
        //}
        #region IMonitor监听
        private void OnMonitorInvoke(DateTime dt, IDevice device, MonitorSet monitorSet)
@@ -618,7 +607,7 @@
                                    res = new ProcessResponse((int)ReturnValue.EXCEPTIONVALUE);
                                }
                                var newEx = new ProcessException("函数" + methodCode + "执行异常", ex);
                                var newEx = new ProcessException("函数" + methodCode + "执行异常", ExceptionLevel.Warning, ex);
                            }
                            else
                            {
@@ -656,64 +645,24 @@
                monitorSet.Response.ResultValue = (int)ReturnValue.OKVALUE;
            }
            #endregion
            //sw.Stop();
            //LogAsync(DateTime.Now, methodCode + " 调用耗时: " + sw.ElapsedMilliseconds.ToString() + "ms", "");
            //TimeRecordCSV(DateTime.Now, methodCode + "调用", (int)sw.ElapsedMilliseconds);
            //sw.Start();
            #region 原有PLC写入结果操作,现转到异步调用后回调去执行
            //ProcessResponse resValues = res as ProcessResponse;
            //if (resValues.ResultValue == (int)PLCReplyValue.IGNORE)
            //{
            //    return;
            //}
            //if (monitorSet.ReplyDataAddress != -1 && resValues.DataList.Count > 0)
            //{
            //    PLC_ITEM item = new PLC_ITEM();
            //    item.OP_TYPE = 2;
            //    item.ITEM_LENGTH = resValues.DataList.Count;
            //    item.ADDRESS = monitorSet.ReplyDataAddress.ToString();
            //    item.ITEM_VALUE = String.Join(",", resValues.DataList);
            //    PLC.WriteItem(item, false);
            //}
            //if (monitorSet.NoticeAddress != -1)
            //{
            //    //测试模式下始终反馈OK信号
            //    if (StationConfig.IsDemoMode && resValues.ResultValue <= 0)
            //    {
            //        resValues.ResultValue = (int)ReturnValue.OKVALUE;
            //    }
            //    int repeatTime = 5;
            //    //LogAsync(DateTime.Now, methodCode + "开始反馈", "");
            //    do
            //    {
            //        try
            //        {
            //            PLC.WriteSingleAddress(set.NoticeAddress, resValues.ResultValue, false);
            //            repeatTime = 0;
            //        }
            //        catch (Exception ex)
            //        {
            //            repeatTime--;
            //            if (repeatTime <= 0)
            //            {
            //                new ProcessException("PLC反馈写入异常", ex);
            //            }
            //        }
            //    } while (repeatTime > 0);
            //}
            #endregion
        }
        private void OnMonitorAlarm(DateTime dt, IDevice device, WarningSet warning, bool isAlarmRaised)
        private void OnMonitorAlarm(DateTime dt, IDevice device, WarningSet warning)
        {
            var bind = Config.AGVBindCollection.FirstOrDefault(u => u.CameraId == device.Id || u.RobotId == device.Id || u.AGVId == device.Id);
            if (bind == null)
            {
                throw new ProcessException($"{device.Name}的异常信息未能获取相关绑定设备信息");
            }
            if (warning.CurrentStatus == warning.TriggerValue)
            {
                bind.WarningMsg.Add(warning.WarningDescription);
                bind.UnitState = AGVState.Warning;
            }
            //暂时不执行自动复位,需要手工复位
        }
        //List<int> _monitorList = new List<int>();
@@ -1173,7 +1122,7 @@
                    else
                    {
                        //MessageBox.Show("未能获取离线图片!");
                        throw new ProcessException("未能获取离线图片!", null);
                        throw new ProcessException("未能获取离线图片!");
                    }
                }
            }
@@ -1437,7 +1386,7 @@
        #endregion
        #region 报警和DownTime
        public ObservableCollection<string> _warningRemains = new ObservableCollection<string>();
        public ObservableCollection<string> WarningRemains { get; set; } = new ObservableCollection<string>();
        bool warningRemainFlag = false;
        bool WarningRemainFlag