patrick
2019-12-10 1c4426810c71eead57084be8a18ade8d314dd8c4
1. 重构项目
22个文件已修改
460 ■■■■■ 已修改文件
src/A032.Config/ConfigFrm.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/AGVBindUnit.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/AGVPath.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessConfig.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl.cs 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl_AGV.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl_Calibration.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl_Method.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl_Robot.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Process/ProcessControl_Task.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Common.Model/Interface/IDeviceConfig.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Common.Model/Interface/IMonitor.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Common.Model/Model/WarningSet.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.AuboRobot/AuboRobotConfig.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.AuboRobot/AuboRobotDriver.cs 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.Common/Base/DeviceBase.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.Common/Base/DeviceConfigBase.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.Common/DeviceBase/CameraBase.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.Common/DeviceBase/PLCBase.cs 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.OmronFins/OmronFinsDriver.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.SeerAGV/SeerAGVConfig.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Bro.Device.SeerAGV/SeerAGVDriver.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/A032.Config/ConfigFrm.cs
@@ -267,21 +267,21 @@
        private void cboCalibrationMethod_SelectedIndexChanged(object sender, EventArgs e)
        {
            //if (cboCalibrationMethod.SelectedIndex >= 0)
            //{
            //    string methodCode = cboCalibrationMethod.SelectedValue.ToString();
            if (cboCalibrationMethod.SelectedIndex >= 0)
            {
                string methodCode = cboCalibrationMethod.SelectedValue.ToString();
            //    _calibrationMethod = _calibrationMethodDict[_calibrationMethodDict.Keys.FirstOrDefault(u => u.MethodCode == methodCode)];
                _calibrationMethod = _calibrationMethodDict[_calibrationMethodDict.Keys.FirstOrDefault(u => u.MethodCode == methodCode)];
            //    if (Process.StationConfig.ProcessOpConfigDict.Keys.Contains(methodCode))
            //    {
            //        propCalibrationConfig.SelectedObject = Process.StationConfig.ProcessOpConfigDict[methodCode];
            //    }
            //    else
            //    {
            //        MessageBox.Show(@"Config of " + methodCode + @" is not found");
            //    }
            //}
                if (Process.StationConfig.ProcessOpConfigDict.Keys.Contains(methodCode))
                {
                    propCalibrationConfig.SelectedObject = Process.StationConfig.ProcessOpConfigDict[methodCode];
                }
                else
                {
                    MessageBox.Show(@"Config of " + methodCode + @" is not found");
                }
            }
        }
        private void btnStartCalibration_Click(object sender, EventArgs e)
@@ -320,7 +320,7 @@
        List<IDevice> _deviceList = new List<IDevice>();
        private void InitialDevices()
        {
            _deviceList = (Process as ProcessControl).GetDeviceList();
            _deviceList = (Process as ProcessControl).DeviceList;
            List<ISimpleDevice> list = _deviceList.Select(u => u as ISimpleDevice).ToList();
            UIHelper.SetCombo(cboCalibDevices, list, "Name", "Id");
src/A032.Process/AGVBindUnit.cs
@@ -8,10 +8,8 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading;
namespace A032.Process
{
@@ -154,7 +152,7 @@
        [Browsable(false)]
        [JsonIgnore]
        public string WarningMsg { get; set; } = "";
        public List<string> WarningMsg { get; set; } = new List<string>();
        #endregion
        #region 设备
@@ -203,6 +201,15 @@
        public AGVBindUnit()
        {
        }
        public void Reset()
        {
            WarningMsg.Clear();
            UnitState = AGVState.Idle;
            AGV.ResetAlarm();
            Robot.ResetAlarm();
        }
    }
    public class AGVDeviceConverter : ComboBoxItemTypeConvert
src/A032.Process/AGVPath.cs
@@ -4,13 +4,9 @@
using Bro.Common.Model.Interface;
using Bro.Device.HikCamera;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace A032.Process
{
src/A032.Process/ProcessConfig.cs
@@ -1,5 +1,4 @@
using Autofac;
using Bro.Common.Base;
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
@@ -10,13 +9,10 @@
using Bro.Device.SeerAGV;
using Bro.Device.Station;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Bro.Common.Helper.EnumHelper;
namespace A032.Process
src/A032.Process/ProcessControl.cs
@@ -3,7 +3,6 @@
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using Bro.Common.PubSub;
using Bro.Device.AuboRobot;
using Bro.Device.OmronFins;
@@ -35,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)
@@ -119,6 +118,8 @@
        Dictionary<string, AuboRobotDriver> RobotDict = new Dictionary<string, AuboRobotDriver>();
        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; }
@@ -296,12 +297,16 @@
            WarningRemains.CollectionChanged -= _warningRemains_CollectionChanged;
            WarningRemains.CollectionChanged += _warningRemains_CollectionChanged;
            #region 设备初始化
            DeviceList = new List<IDevice>();
            InitialPLCs();
            InitialAGVs();
            InitialRobots();
            InitialCameras();
            InitialAGVBindUnit();
            //InitialMachineTrayNums();
            #endregion
            AutoFacRegister();
@@ -345,6 +350,8 @@
                CameraBase camera = CameraHelper.GetCameraInstance(c.DriverType);
                camera.InitialConfig = c;
                CameraDict[camera.InitialConfig.ID] = camera;
                DeviceList.Add(camera);
            });
        }
@@ -361,6 +368,8 @@
                plc.OnMonitorAlarm += OnMonitorAlarm;
                plc.OnMonitorInvoke += OnMonitorInvoke;
                DeviceList.Add(plc);
            });
        }
@@ -381,6 +390,8 @@
                robot.OnMonitorAlarm += OnMonitorAlarm;
                robot.OnMonitorInvoke += OnMonitorInvoke;
                DeviceList.Add(robot);
            });
        }
@@ -395,10 +406,15 @@
                agv.OnMonitorAlarm -= OnMonitorAlarm;
                agv.OnMonitorInvoke -= OnMonitorInvoke;
                agv.OnMonitorAlarm += OnMonitorAlarm;
                agv.OnMonitorInvoke += OnMonitorInvoke;
                agv.OnLog = OnDeviceLog;
                agv.OnAGVPositoinChanged = OnAGVPositionChanged;
                agv.OnAGVTaskStatusChanged = OnAGVTaskStatusChanged;
                agv.OnAGVBatteryLvlChanged = OnAGVBatteryLvlChanged;
                DeviceList.Add(agv);
            });
        }
@@ -542,17 +558,17 @@
            });
        }
        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)
@@ -631,8 +647,22 @@
            #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>();
src/A032.Process/ProcessControl_AGV.cs
@@ -1,9 +1,6 @@
using Bro.Common.Helper;
using Bro.Device.SeerAGV;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace A032.Process
@@ -28,8 +25,9 @@
                        if (chargePosition == null)
                        {
                            bind.WarningMsg = $"{bind.AGV.Name}目前无可用充电地址";
                            new ProcessException(bind.WarningMsg);
                            string warningMsg = $"{bind.AGV.Name}目前无可用充电地址";
                            bind.WarningMsg.Add(warningMsg);
                            new ProcessException(warningMsg);
                            bind.UnitState = AGVState.Warning;
                        }
                        else
src/A032.Process/ProcessControl_Calibration.cs
@@ -1,5 +1,4 @@
using A032.Process.Calibration;
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
@@ -8,9 +7,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Bro.Common.Helper.EnumHelper;
namespace A032.Process
src/A032.Process/ProcessControl_Method.cs
@@ -1,21 +1,7 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
using Bro.Device.AuboRobot;
using Bro.Device.HikCamera;
using Bro.Device.SeerAGV;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace A032.Process
{
src/A032.Process/ProcessControl_Robot.cs
@@ -1,9 +1,5 @@
using Bro.Device.AuboRobot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace A032.Process
{
src/A032.Process/ProcessControl_Task.cs
@@ -9,12 +9,9 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -176,8 +173,9 @@
                {
                    if (bind.UnitState == AGVState.Warning)
                    {
                        bind.WarningMsg = "";
                        bind.UnitState = AGVState.Idle;
                        //bind.WarningMsg.Clear();
                        //bind.UnitState = AGVState.Idle;
                        bind.Reset();
                    }
                });
@@ -189,8 +187,10 @@
                if (bind != null && bind.UnitState == AGVState.Warning)
                {
                    bind.WarningMsg = "";
                    bind.UnitState = AGVState.Idle;
                    //bind.WarningMsg.Clear();
                    //bind.UnitState = AGVState.Idle;
                    bind.Reset();
                    LogAsync(DateTime.Now, "Reset", $"执行{bind.AGV.Name}复位操作");
                }
@@ -287,7 +287,7 @@
            }
            else
            {
                bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == unitId);
                bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == unitId && (u.UnitState == AGVState.Idle || u.UnitState == AGVState.IdleCharge));
            }
            if (bind == null)
@@ -436,7 +436,7 @@
            bind.CurrentTaskId = "";
            if (isWarningRaised)
            {
                bind.WarningMsg = warningMsg;
                bind.WarningMsg.Add(warningMsg);
                bind.UnitState = AGVState.Warning;
            }
            else
@@ -447,8 +447,9 @@
                if (!isNotTimeout)
                {
                    bind.WarningMsg = $"{bind.AGV.Name}获取电池状态超时";
                    new ProcessException(bind.WarningMsg);
                    string msg = $"{bind.AGV.Name}获取电池状态超时";
                    bind.WarningMsg.Add(msg);
                    new ProcessException(msg);
                    bind.UnitState = AGVState.Warning;
                }
                else
@@ -462,8 +463,9 @@
                        if (chargePosition == null)
                        {
                            bind.WarningMsg = $"{bind.AGV.Name}目前无可用充电地址";
                            new ProcessException(bind.WarningMsg);
                            string msg = $"{bind.AGV.Name}目前无可用充电地址";
                            bind.WarningMsg.Add(msg);
                            new ProcessException(msg);
                            bind.UnitState = AGVState.Warning;
                        }
                        else
src/Bro.Common.Model/Interface/IDeviceConfig.cs
@@ -1,4 +1,6 @@
using System;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -35,6 +37,15 @@
        string DriverType { get; set; }
    }
    public interface IMonitorInitialConfig
    {
        bool IsEnableMonitor { get; set; }
        int ScanInterval { get; set; }
        int Timeout { get; set; }
        List<WarningSet> WarningSetCollection { get; set; }
        List<MonitorSet> MonitorSetCollection { get; set; }
    }
    public interface ILog
    {
        string LogPath { get; set; }
src/Bro.Common.Model/Interface/IMonitor.cs
@@ -8,11 +8,12 @@
namespace Bro.Common.Model.Interface
{
    public delegate void OnMonitorInvokeDelegate(DateTime dt, IDevice device, MonitorSet monitorSet);
    public delegate void OnMonitorAlarmDelegate(DateTime dt, IDevice device, WarningSet warning, bool isAlarmRaised);
    public delegate void OnMonitorAlarmDelegate(DateTime dt, IDevice device, WarningSet warning);
    public interface IMonitor
    {
        //List<int> GetMonitorValues(int startAddress, int length);
        void Monitor();
        void ResetAlarm();
        event OnMonitorInvokeDelegate OnMonitorInvoke;
        event OnMonitorAlarmDelegate OnMonitorAlarm;
src/Bro.Common.Model/Model/WarningSet.cs
@@ -1,4 +1,5 @@
using Bro.Common.Helper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -14,28 +15,37 @@
    /// </summary>
    public class WarningSet : IComplexDisplay
    {
        [Category("警报设置")]
        [Description("警报位索引")]
        public int WaringIndex { get; set; }
        [Category("索引设置")]
        [Description("警报索引——字索引")]
        public int WarningIndex_Word { get; set; }
        [Category("警报设置")]
        [Category("索引设置")]
        [Description("警报索引——位索引")]
        public int WarningIndex_Bit { get; set; }
        [Category("触发设置")]
        [Description("true:高电平触发报警 false:低电平触发报警")]
        public bool TriggerValue { get; set; } = true;
        [Category("警报内容")]
        [Description("警报代码")]
        public string WarningCode { get; set; }
        [Category("警报设置")]
        [Category("警报内容")]
        [Description("警报描述")]
        public string WarningDescription { get; set; }
        [Category("警报设置")]
        [Category("级别设置")]
        [Description("警报级别")]
        public int WarningLvl { get; set; } = 0;
        [Description("报警工位")]
        public int WorkPosition { get; set; } = 0;
        [Browsable(false)]
        [JsonIgnore]
        public bool CurrentStatus { get; set; } = false;
        public string GetDisplayText()
        {
            return WaringIndex + "-" + WarningCode + "-" + WarningDescription + "-" + WorkPosition;
            return $"{WarningIndex_Word}:{WarningIndex_Bit}-{WarningCode}-{WarningDescription}";
        }
    }
}
src/Bro.Device.AuboRobot/AuboRobotConfig.cs
@@ -1,6 +1,7 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
@@ -9,7 +10,7 @@
namespace Bro.Device.AuboRobot
{
    [Device("AuboRobot", "奥博机器人", EnumHelper.DeviceAttributeType.InitialConfig)]
    public class AuboRobotInitialConfig : InitialConfigBase
    public class AuboRobotInitialConfig : InitialMonitorConfigBase
    {
        [Category("机器人设置")]
        [Description("机器人通信IP")]
@@ -39,36 +40,27 @@
        [Description("动作超时设置,单位min")]
        public float OperationTimeout { get; set; } = 1;
        [Category("IO监听设置")]
        [Description("IO监听操作配置集合")]
        [Category("通信报警配置")]
        [Description("通信过程中反馈报警代码配置")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        [Category("IO监听设置")]
        [Description("IO监听间隔,以ms为单位")]
        public int ScanInterval { get; set; } = 9999;
        [Category("IO监听设置")]
        [Description("是否启用IO监听,true:监听 false:不监听")]
        public bool IsEnableMonitor { get; set; } = false;
        [Category("报警配置")]
        [Description("报警代码配置")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<RobotWarningCode>), typeof(UITypeEditor))]
        public List<RobotWarningCode> RobotWarnings { get; set; } = new List<RobotWarningCode>();
        [Editor(typeof(ComplexCollectionEditor<RobotReplyWarningCode>), typeof(UITypeEditor))]
        public List<RobotReplyWarningCode> RobotReplyWarnings { get; set; } = new List<RobotReplyWarningCode>();
    }
    public class RobotWarningCode
    public class RobotReplyWarningCode : IComplexDisplay
    {
        [Category("报警配置")]
        [Category("反馈报警配置")]
        [Description("报警代码")]
        public int WarningCode { get; set; }
        [Category("报警配置")]
        [Category("反馈报警配置")]
        [Description("报警代码描述")]
        public string WarningDescription { get; set; }
        public string GetDisplayText()
        {
            return $"{WarningCode}-{WarningDescription}";
        }
    }
    [Device("AuboRobot", "奥博机器人", EnumHelper.DeviceAttributeType.OperationConfig)]
src/Bro.Device.AuboRobot/AuboRobotDriver.cs
@@ -67,14 +67,13 @@
            //Query Robot IOs
            //SendMsg(RobotMsgType.Send, 0, true, RobotMsgAction.IO, RobotMsgParas.Query, new List<string>());
            //scanMsg = new RobotMsg();
            //scanMsg.Action = RobotMsgAction.IO;
            //scanMsg.Para1 = RobotMsgParas.Query;
            scanMsg = new RobotMsg();
            scanMsg.Action = RobotMsgAction.IOQuery;
            //Task.Run(() =>
            //{
            //    Monitor();
            //});
            Task.Run(() =>
            {
                Monitor();
            });
        }
        protected override void Stop()
@@ -309,7 +308,7 @@
                    if (errorCode != 0)
                    {
                        var desc = IConfig.RobotWarnings.FirstOrDefault(u => u.WarningCode == errorCode);
                        var desc = IConfig.RobotReplyWarnings.FirstOrDefault(u => u.WarningCode == errorCode);
                        throw new ProcessException($"{Name}{msg.ID}任务反馈异常{errorCode},异常描述:{(desc == null ? "无" : desc.WarningDescription)}");
                    }
@@ -508,6 +507,19 @@
        protected virtual void MonitorCheckAndInvoke(List<int> tempNew, List<int> tempOld)
        {
            IConfig.WarningSetCollection.ForEach(w =>
            {
                if (w.WarningIndex_Word < 0 || w.WarningIndex_Word >= tempNew.Count)
                    return;
                bool isOn = tempNew[w.WarningIndex_Word] == 1;
                if (w.CurrentStatus != isOn)
                {
                    w.CurrentStatus = isOn;
                    OnMonitorAlarm?.BeginInvoke(DateTime.Now, this, w, null, null);
                }
            });
            IConfig.MonitorSetCollection.ForEach(m =>
            {
                if (m.TriggerIndex < 0 || m.TriggerIndex >= tempNew.Count)
@@ -537,6 +549,11 @@
                }
            });
        }
        public virtual void ResetAlarm()
        {
            IConfig.WarningSetCollection.ForEach(u => u.CurrentStatus = !u.TriggerValue);
        }
        #endregion
    }
}
src/Bro.Device.Common/Base/DeviceBase.cs
@@ -30,7 +30,6 @@
        public Action<EnumHelper.DeviceState> OnDeviceStateChanged { get; set; }
        #endregion
        int RetryTime = 3;
        /// <summary>
        /// 和设备暂停状态关联的信号量
@@ -169,8 +168,6 @@
        [JsonIgnore]
        public Dictionary<DeviceInputMethodAttribute, MethodInfo> InputMethods { get; set; } = new Dictionary<DeviceInputMethodAttribute, MethodInfo>();
        //public event DeviceStateChangedDelegate OnDeviceStateChanged;
src/Bro.Device.Common/Base/DeviceConfigBase.cs
@@ -1,5 +1,7 @@
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -43,5 +45,52 @@
        [Category("日志配置")]
        [Description("true:启用日志记录  false:不启用日志记录")]
        public bool IsEnableLog { get; set; } = false;
        public virtual List<string> GetHalconToolPathList()
        {
            return new List<string>();
        }
    }
    public class InitialMonitorConfigBase : InitialConfigBase, IMonitorInitialConfig, IHalconToolPath
    {
        [Category("监听设置")]
        [Description("true:启用监听 false:不启用监听")]
        public bool IsEnableMonitor { get; set; } = true;
        [Category("监听设置")]
        [Description("扫描间隔时间,单位:ms")]
        public int ScanInterval { get; set; } = 100;
        [Category("监听设置")]
        [Description("超时设置,单位:ms")]
        public int Timeout { get; set; } = 500;
        [Category("监听设置")]
        [Description("警报配置列表")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<WarningSet>), typeof(UITypeEditor))]
        public List<WarningSet> WarningSetCollection { get; set; } = new List<WarningSet>();
        [Category("监听设置")]
        [Description("监听操作配置集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        public new virtual List<string> GetHalconToolPathList()
        {
            return MonitorSetCollection.SelectMany(u =>
            {
                if (u.OpConfig is IHalconToolPath)
                {
                    return (u.OpConfig as IHalconToolPath).GetHalconToolPathList();
                }
                else
                {
                    return new List<string>();
                }
            }).ToList();
        }
    }
}
src/Bro.Device.Common/DeviceBase/CameraBase.cs
@@ -654,7 +654,7 @@
        [Category("相机设置")]
        [Description("驱动类型")]
        [TypeConverter(typeof(CameraTypeConverter))]
        public string DriverType { get; set; } = "HikCamera";
        public new string DriverType { get; set; } = "HikCamera";
        [Category("相机设置")]
        [Description("相机序列号")]
src/Bro.Device.Common/DeviceBase/PLCBase.cs
@@ -58,8 +58,6 @@
                        if (newValues == null || newValues.Count == 0)
                            continue;
                        //Stopwatch sw = new Stopwatch();
                        //sw.Start();
                        if (oldValues.Count == newValues.Count)
                        {
                            var tempNew = new List<int>(newValues);
@@ -67,13 +65,6 @@
                            MonitorCheckAndInvoke(tempNew, tempOld);
                        }
                        oldValues = new List<int>(newValues);
                        //sw.Stop();
                        //if (sw.ElapsedMilliseconds > 10)
                        //{
                        //    LogAsync(DateTime.Now, $"轮询时间:{sw.ElapsedMilliseconds}", "");
                        //    TimeRecordCSV(DateTime.Now, "轮询时间", (int)sw.ElapsedMilliseconds);
                        //}
                        Thread.Sleep(PLCIConfig.ScanInterval);
                    }
@@ -88,42 +79,31 @@
        protected virtual void MonitorCheckAndInvoke(List<int> tempNew, List<int> tempOld)
        {
            #region PLC警报信息
            //bool warningSignal = (m.TriggerIndex >= PLCIConfig.WarningStartIndex && m.TriggerIndex < PLCIConfig.WarningStartIndex + PLCIConfig.WarningLength);
            PLCIConfig.WarningSetCollection.ForEach(w =>
            {
                if (w.WarningIndex_Word < 0 || w.WarningIndex_Word >= tempNew.Count)
                    return;
            //if (warningSignal)
            //{
            //    if (newValue != oldValue)
            //    {
            //        int warningIndex = m.TriggerIndex - PLCIConfig.WarningStartIndex;
            //        for (int i = 0; i < 16; i++)
            //        {
            //            var ws = PLCIConfig.WarningSetCollection.FirstOrDefault(w => w.WaringIndex == (warningIndex * 16) + i);
                if (w.WarningIndex_Bit < 0 || w.WarningIndex_Bit > 16)
                    return;
            //            if (ws != null)
            //            {
            //                int newAlarmValue = newValue >> i & 1;
            //                int oldAlarmValue = oldValue >> i & 1;
                bool isOn = ((tempNew[w.WarningIndex_Word] >> w.WarningIndex_Bit) & 1) == 1;
            //                if (newAlarmValue != oldAlarmValue)
            //                {
            //                    OnMonitorAlarm?.BeginInvoke(ws, newAlarmValue == 1, null, null);
            //                    //仅保存警报信息,不保存提示信息
            //                    //if (ws.WarningLvl == 0)
            //                    //{
            //                    //    SaveAlarm(Config.StationCode, ws, newValue);
            //                    //}
            //                }
            //            }
            //        }
            //    }
            //    return;
            //}
                if (w.CurrentStatus != isOn)
                {
                    w.CurrentStatus = isOn;
                    OnMonitorAlarm?.BeginInvoke(DateTime.Now, this, w, null, null);
                }
            });
            #endregion
            PLCIConfig.MonitorSetCollection.ForEach(m =>
            {
                if (m.TriggerIndex < 0 || m.TriggerIndex >= tempNew.Count)
                {
                    return;
                }
                int newValue = tempNew[m.TriggerIndex];
                int oldValue = tempOld[m.TriggerIndex];
@@ -192,6 +172,11 @@
                } while (repeatTime > 0);
            }
        }
        public virtual void ResetAlarm()
        {
            PLCIConfig.WarningSetCollection.ForEach(u => u.CurrentStatus = !u.TriggerValue);
        }
        #endregion
    }
@@ -212,36 +197,8 @@
    {
    }
    public class PLCInitialConfigBase : InitialConfigBase
    public class PLCInitialConfigBase : InitialMonitorConfigBase
    {
        [Category("监听设置")]
        [Description("警报配置列表")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<WarningSet>), typeof(UITypeEditor))]
        public List<WarningSet> WarningSetCollection { get; set; } = new List<WarningSet>();
        [Category("监听设置")]
        [Description("监听操作配置集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        [Category("监听设置")]
        [Description("扫描间隔时间,单位:ms")]
        public int ScanInterval { get; set; } = 100;
        [Category("监听设置")]
        [Description("超时设置,单位:ms")]
        public int Timeout { get; set; } = 500;
        //[Category("输出设置")]
        //[Description("是否日志输出")]
        //public bool IsEnabelLog { get; set; } = false;
        //[Category("输出设置")]
        //[Description("输出文件路径")]
        //public string LogPath { get; set; } = @"D:\PLCLog.txt";
        #region 地址设置
        [Category("事件地址设置")]
        [Description("事件开始地址,PLC的实际寄存器地址。十进制,不包含功能码。")]
src/Bro.Device.OmronFins/OmronFinsDriver.cs
@@ -17,7 +17,7 @@
namespace Bro.Device.OmronFins
{
    public class OmronFinsDriver : PLCBase, IMonitor
    public class OmronFinsDriver : PLCBase
    {
        #region PLCBase
        public override void Read(PLCOperationConfigBase config)
src/Bro.Device.SeerAGV/SeerAGVConfig.cs
@@ -11,7 +11,7 @@
namespace Bro.Device.SeerAGV
{
    [Device("SeerAGV", "SeerAGV", EnumHelper.DeviceAttributeType.InitialConfig)]
    public class SeerAGVInitialConfig : InitialConfigBase
    public class SeerAGVInitialConfig : InitialMonitorConfigBase
    {
        [Category("通信配置")]
        [Description("AGVIP地址")]
@@ -25,21 +25,21 @@
        [Description("导航端口")]
        public int GuidePort { get; set; } = 19206;
        [Category("监听配置")]
        [Description("监听间隔,单位ms")]
        public int ScanInterval { get; set; } = 500;
        //[Category("监听配置")]
        //[Description("监听的IO信息配置集合")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
        //public List<IODefinition> IOCollection { get; set; } = new List<IODefinition>();
        //[Description("监听间隔,单位ms")]
        //public int ScanInterval { get; set; } = 500;
        [Category("监听设置")]
        [Description("监听操作配置集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        ////[Category("监听配置")]
        ////[Description("监听的IO信息配置集合")]
        ////[TypeConverter(typeof(CollectionCountConvert))]
        ////[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
        ////public List<IODefinition> IOCollection { get; set; } = new List<IODefinition>();
        //[Category("监听设置")]
        //[Description("监听操作配置集合")]
        //[TypeConverter(typeof(CollectionCountConvert))]
        //[Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        //public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        [Category("监听配置")]
        [Description("是否采用简单监听模式。true:简单模式,只获取任务状态;false:全部模式,获取任务所有信息")]
src/Bro.Device.SeerAGV/SeerAGVDriver.cs
@@ -102,7 +102,7 @@
            _taskDoneHandle.Set();
            _monitorLock.Set();
            if (client_Guide != null && client_Guide.Connected)
            {
                CancelTask();
@@ -440,6 +440,11 @@
                }
            }
        }
        public virtual void ResetAlarm()
        {
            IConfig.WarningSetCollection.ForEach(u => u.CurrentStatus = !u.TriggerValue);
        }
        #endregion
    }
}