src/A032.Process/AGVBindUnit.cs
@@ -15,42 +15,84 @@
namespace A032.Process
{
    public enum TaskStatus
    public enum TaskState
    {
        Available = 1,
        /// <summary>
        /// 新任务
        /// </summary>
        New = 0,
        /// <summary>
        /// 任务完成
        /// </summary>
        Done = 1,
        /// <summary>
        /// 任务失败
        /// </summary>
        Failed = 2,
        /// <summary>
        /// 任务已添加队列,等待执行
        /// </summary>
        Queueing = 3,
        /// <summary>
        /// 任务已指派
        /// </summary>
        Assigned = 4,
        /// <summary>
        /// 任务未指派,已取消
        /// </summary>
        Cancelled = 5,
    }
    public enum AGVState
    {
        /// <summary>
        /// AGV状态不可知
        /// </summary>
        Unknown = 0,
        /// <summary>
        /// 空闲状态,可接收任务
        /// </summary>
        Idle = 1,
        /// <summary>
        /// 任务执行中
        /// </summary>
        Running = 2,
        /// <summary>
        /// 报警中,不可执行任务
        /// </summary>
        Warning = 3,
        /// <summary>
        /// 充电中,不可执行任务
        /// </summary>
        InCharge = 4,
        /// <summary>
        /// 空闲充电状态,可接收任务
        /// </summary>
        IdleCharge = 5,
    }
    public enum TaskAvailableLevel
    {
        Robot = 1,
        AGV = 2,
        Both = 3,
    }
    //public class AGVTaskModel
    //{
    //    public TaskAvailableLevel Level { get; set; } = TaskAvailableLevel.Robot;
    public class AGVTaskModel
    {
        public TaskAvailableLevel Level { get; set; } = TaskAvailableLevel.Robot;
    //    public string MethodName { get; set; }
        public string MethodName { get; set; }
    //    public IOperationConfig OpConfig { get; set; }
        public IOperationConfig OpConfig { get; set; }
    //    public IDevice Device { get; set; }
        public IDevice Device { get; set; }
    //    //public int Priority { get; set; } = 10;
        //public int Priority { get; set; } = 10;
    //    public AGVTaskModel() { }
        public AGVTaskModel() { }
        public AGVTaskModel(TaskAvailableLevel level, string methodName, IOperationConfig opConfig = null, IDevice device = null)
        {
            Level = level;
            MethodName = methodName;
            OpConfig = opConfig ?? new OperationConfigBase();
            Device = device;
        }
    }
    //    public AGVTaskModel(TaskAvailableLevel level, string methodName, IOperationConfig opConfig = null, IDevice device = null)
    //    {
    //        Level = level;
    //        MethodName = methodName;
    //        OpConfig = opConfig ?? new OperationConfigBase();
    //        Device = device;
    //    }
    //}
    public class AGVBindUnit : IComplexDisplay
    {
@@ -90,60 +132,32 @@
        }
        #endregion
        #region 后台属性
        #region 状态
        private AGVState unitState = AGVState.Idle;
        [Browsable(false)]
        [JsonIgnore]
        public Action<AGVTaskModel> OnMethodInvoke { get; set; }
        public string AGVDest { get; set; } = "";
        private TaskStatus agvStatus = TaskStatus.Available;
        [Browsable(false)]
        [JsonIgnore]
        public TaskStatus AGVStatus
        public AGVState UnitState
        {
            get => agvStatus;
            get => unitState;
            set
            {
                agvStatus = value;
                //InvokeTaskCheck();
            }
        }
                if (value != unitState)
                {
                    var preState = unitState;
                    unitState = value;
        private TaskStatus robotStatus = TaskStatus.Available;
        [Browsable(false)]
        [JsonIgnore]
        public TaskStatus RobotStatus
        {
            get => robotStatus;
            set
            {
                robotStatus = value;
                //InvokeTaskCheck();
                    OnUnitStateChanged?.Invoke(this.Id, preState, unitState);
                }
            }
        }
        [Browsable(false)]
        [JsonIgnore]
        public TaskStatus UnitStatus
        {
            get
            {
                if (AGVStatus == TaskStatus.Warning || RobotStatus == TaskStatus.Warning)
                {
                    return TaskStatus.Warning;
                }
                else
                {
                    if (AGVStatus == TaskStatus.Available && RobotStatus == TaskStatus.Available)
                    {
                        return TaskStatus.Available;
                    }
                }
        public string WarningMsg { get; set; } = "";
        #endregion
                return TaskStatus.Running;
            }
        }
        #region 设备
        [Browsable(false)]
        [JsonIgnore]
        public SeerAGVDriver AGV { get; set; } = null;
@@ -153,144 +167,42 @@
        [Browsable(false)]
        [JsonIgnore]
        public CameraBase Camera { get; set; } = null;
        #endregion
        //[Browsable(false)]
        //[JsonIgnore]
        //public ObservableCollection<AGVTaskModel> TaskList { get; set; } = new ObservableCollection<AGVTaskModel>();
        #region 任务信息
        [JsonIgnore]
        [Browsable(false)]
        public string CurrentTaskId { get; set; }
        [Browsable(false)]
        [JsonIgnore]
        public int CurrentEmptyTray { get; set; }
        [Browsable(false)]
        [JsonIgnore]
        public int CurrentFullTray { get; set; }
        [Browsable(false)]
        [JsonIgnore]
        public bool IsFullTrayFull { get; set; }
        [Browsable(false)]
        [JsonIgnore]
        public bool IsFullTrayEmpty { get; set; }
        [Browsable(false)]
        [JsonIgnore]
        public bool IsEmptyTrayEmpty { get; set; }
        public bool IsTaskCancelled { get; set; } = false;
        [Browsable(false)]
        [JsonIgnore]
        public bool IsFullTrayTaskAssigned { get; set; }
        [Browsable(false)]
        public bool IsTaskCancelling { get; set; } = false;
        #endregion
        [Browsable(false)]
        #region 事件
        [JsonIgnore]
        public bool IsEmptyTrayTaskAssigned { get; set; }
        [Browsable(false)]
        public Action<string, AGVState, AGVState> OnUnitStateChanged { get; set; }
        #endregion
        [Browsable(false)]
        #region 托盘信息
        [JsonIgnore]
        public ManualResetEvent RobotIOHandle { get; set; } = new ManualResetEvent(false);
        [Browsable(false)]
        public int FullTrayNum { get; set; }
        [JsonIgnore]
        [Browsable(false)]
        public int EmptyTrayNum { get; set; }
        #endregion
        #endregion
        public AGVBindUnit()
        {
            //TaskList.CollectionChanged += TaskList_CollectionChanged;
        }
        object agvStatusLock = new object();
        public bool SetAGVStatus(TaskStatus status)
        {
            lock (agvStatusLock)
            {
                switch (status)
                {
                    case TaskStatus.Available:
                        break;
                    case TaskStatus.Running:
                        if (AGVStatus == TaskStatus.Available)
                        {
                            AGVStatus = status;
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    case TaskStatus.Warning:
                        break;
                    default:
                        break;
                }
                AGVStatus = status;
                return true;
            }
        }
        //private void TaskList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        //{
        //    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        //    {
        //        InvokeTaskCheck();
        //    }
        //}
        //private void InvokeTaskCheck()
        //{
        //    lock (taskLock)
        //    {
        //        for (int i = 0; i < TaskList.Count; i++)
        //        {
        //            var task = TaskList[i];
        //            bool isAgvOK = false;
        //            bool isRobotOK = false;
        //            if ((task.Level & TaskAvailableLevel.AGV) == TaskAvailableLevel.AGV)
        //            {
        //                isAgvOK = AGVStatus == TaskStatus.Available;
        //            }
        //            else
        //            {
        //                isAgvOK = true;
        //            }
        //            if ((task.Level & TaskAvailableLevel.Robot) == TaskAvailableLevel.Robot)
        //            {
        //                isRobotOK = RobotStatus == TaskStatus.Available;
        //            }
        //            else
        //            {
        //                isRobotOK = true;
        //            }
        //            if (isRobotOK && isAgvOK)
        //            {
        //                OnMethodInvoke?.Invoke(TaskList[i]);
        //                TaskList.RemoveAt(i);
        //                break;
        //            }
        //        }
        //    }
        //}
        //object taskLock = new object();
        //public void AddTask(AGVTaskModel task)
        //{
        //    lock (taskLock)
        //    {
        //        TaskList.Add(task);
        //    }
        //}
        //public void ClearTask()
        //{
        //    lock (taskLock)
        //    {
        //        TaskList.Clear();
        //    }
        //}
        //public AGVTaskModel GetTask(int index)
        //{
        //    lock (taskLock)
        //    {
        //        return TaskList[index];
        //    }
        //}
    }
    public class AGVDeviceConverter : ComboBoxItemTypeConvert
@@ -358,4 +270,40 @@
            }
        }
    }
    public class AllDeviceIdConverter : ComboBoxItemTypeConvert
    {
        public override void GetConvertHash()
        {
            using (var scope = GlobalVar.Container.BeginLifetimeScope())
            {
                _hash[""] = "未指定";
                List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
                deviceList.ForEach(d =>
                {
                    _hash[d.Id] = d.Name;
                });
            }
        }
    }
    public class AllDeviceNameConverter : ComboBoxItemTypeConvert
    {
        public override void GetConvertHash()
        {
            using (var scope = GlobalVar.Container.BeginLifetimeScope())
            {
                _hash[""] = "未指定";
                List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
                deviceList.ForEach(d =>
                {
                    _hash[d.Name] = d.Name;
                });
            }
        }
    }
}