Control.cs 11.9 KB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using Common;
using log4net.Util;
using RestSharp;

namespace DeviceLibrary
{
    public class Control
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger("Control");
        private System.Timers.Timer AgvCallTimer;
        private System.Timers.Timer AgvStateTimer;
        private System.Timers.Timer NodeStateTimer;
        //public List<string> Marks;
        private const int REG_STATUS = 20;
        //private List<string> shelfLockedNodeNames;
        public delegate void AgvChangedEvent(int agvIndex);
        public event AgvChangedEvent AgvChanged;
        public event AgvChangedEvent AgvOnline;
        public event AgvChangedEvent NodeChangedEvent;
        public Control()
        {
            AgvCallTimer = new System.Timers.Timer
            {
                Interval = 300,
                AutoReset = true,
                Enabled = false
            };
            AgvCallTimer.Elapsed += AgvCallTimer_Elapsed;

            AgvStateTimer = new System.Timers.Timer
            {
                Interval = 3000,
                AutoReset = true,
                Enabled = false
            };
            AgvStateTimer.Elapsed += AgvStateTimer_Elapsed;
            NodeStateTimer = new System.Timers.Timer
            {
                Interval = 5000,
                AutoReset = true,
                Enabled = false
            };
           // NodeStateTimer.Elapsed += NodeStateTimer_Elapsed;
        }


        public void Start()
        {
            AgvCallTimer.Enabled = true;
            AgvStateTimer.Enabled = true;
            NodeStateTimer.Enabled = true;
            AgvCallTimer.Start();
            AgvStateTimer.Start();
            NodeStateTimer.Start();
        }

        public void Stop()
        {
            AgvCallTimer.Enabled = false;
            AgvStateTimer.Enabled = false;
            NodeStateTimer.Enabled = false;
            AgvCallTimer.Stop();
            AgvStateTimer.Stop();
            NodeStateTimer.Stop();
        }
        private bool NodeStateInProcess = false;
        //private void NodeStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        //{
        //    if (NodeStateInProcess) return;
        //    NodeStateInProcess = true;
        //    List<AlarmMsg> msglist = new List<AlarmMsg>();
        //    try
        //    {
        //        String tmp = "";
        //        for (int j = 0; j < AGVManager.nodeInfo.Count; j++)
        //        {
        //            bool isAlarm = false;
        //            if (!AGVManager.UpdateStationState(AGVManager.nodeInfo[j]))
        //            {
        //                isAlarm = true;
        //                msglist.Add(new AlarmMsg(AGVManager.nodeInfo[j].AliceName, "lineAgv." + AGVManager.nodeInfo[j].Name + ".WarnMsg", AGVManager.nodeInfo[j].WarnMsg));
        //            }
        //            if (!isAlarm && !AGVManager.nodeInfo[j].Online)
        //            {
        //                msglist.Add(new AlarmMsg(AGVManager.nodeInfo[j].AliceName, "lineAgv." + AGVManager.nodeInfo[j].Name + ".OffLine", "离线"));
        //            }
        //            if (AGVManager.nodeInfo[j].Name.StartsWith(SettingString.RoomS_Name_Prefix) || AGVManager.nodeInfo[j].Name.StartsWith(SettingString.RoomC_Name_Prefix))
        //            {
        //                if (!AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomCFeederIn) && !AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomCFeederOut) &&
        //                    !AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomDFeederIn) && !AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomDFeederOut))
        //                {
        //                    tmp = HttpManager.GetFirstRFID(AGVManager.nodeInfo[j].LineName);
        //                    if (!tmp.Equals(AGVManager.nodeInfo[j].RFID))
        //                    {
        //                        AGVManager.nodeInfo[j].RFID = tmp;
        //                        NodeChangedEvent?.Invoke(j);
        //                    }

        //                }
        //                //if (AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomCFeederOut) || AGVManager.nodeInfo[j].Name.Equals(SettingString.RoomDFeederOut))
        //                //{
        //                //    if (AGVManager.unlockManager.GetUnlockCnt(AGVManager.nodeInfo[j].Name) > 0)
        //                //    {
        //                //        tmp = AGVManager.unlockManager.GetUnlockRfids(AGVManager.nodeInfo[j].Name)[0];
        //                //        if (!tmp.Equals(AGVManager.nodeInfo[j].RFID))
        //                //        {
        //                //            AGVManager.nodeInfo[j].RFID = tmp;
        //                //            NodeChangedEvent?.Invoke(j);
        //                //        }

        //                //    }

        //                //}
        //            }
        //        }
        //        HttpManager.updateDeviceAlarmMsg(msglist);
        //    }
        //    catch (Exception ex)
        //    {
        //        log.Error("NodeStateTimer " + ex.Message + ex.StackTrace);
        //    }
        //    NodeStateInProcess = false;
        //}
        private bool AgvStateInProcess = false;
        //private eAGVState preAGVState = eAGVState.None;
        private void AgvStateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            bool rtn;
            if (AgvStateInProcess) return;
            AgvStateInProcess = true;
            List<AlarmMsg> msglist = new List<AlarmMsg>();
            for (int i = 0; i < AGVManager.agvInfo.Count; i++)
            {
                //上报异常
                bool isAlarm = false;
                try
                {
                    if (!CheckOnline(i)) continue;
                    bool change = false;
                    MiR_API.Get_Task_State(AGVManager.agvInfo[i], out string taskStateStr);
                    Thread.Sleep(50);
                    //获取AGV状态
                    rtn = MiR_API.Get_State(AGVManager.agvInfo[i], out eAGVState stateID, out string stateText, out int battery, out string mission_text, out Agv_Info.MirPosition position);
                    Thread.Sleep(50);
                     change = AGVManager.agvInfo[i].SetState(stateID, taskStateStr, battery, mission_text, position);

                    // if (change)
                    {
                        AgvChanged?.Invoke(i);
                    }

                    Thread.Sleep(50);
                    if (stateText.Equals("Error") || stateText.Equals("EmergencyStop") || stateText.Equals("Pause"))
                    {
                        isAlarm = true;
                        msglist.Add(new AlarmMsg(AGVManager.agvInfo[i].Name, "lineAgv." + AGVManager.agvInfo[i].Name + ".Msg", "状态:" + stateText + ""));
                    }

                    if (!isAlarm && AGVManager.agvInfo[i].StandTimeOut)
                    {
                        isAlarm = true;
                        msglist.Add(new AlarmMsg(AGVManager.agvInfo[i].Name, "lineAgv." + AGVManager.agvInfo[i].Name + ".Msg", "在" + AGVManager.agvInfo[i].PlaceAliceName + "停留超时" + (DateTime.Now - AGVManager.agvInfo[i].StandStartTime).TotalMinutes.ToString("f2") + "分钟"));
                    }

                    if (!isAlarm)
                    {
                        try
                        {
                            if (!AGVManager.agvInfo[i].Msg.Equals(""))
                                msglist.Add(new AlarmMsg(AGVManager.agvInfo[i].Name, "lineAgv." + AGVManager.agvInfo[i].Name + ".Msg", AGVManager.agvInfo[i].Msg, 1));
                            else
                            {
                                if ((AGVManager.agvInfo[i].Place.Contains(SettingString.AutoCharge) || AGVManager.agvInfo[i].Place.Contains(SettingString.Standby)))
                                {
                                    msglist.Add(new AlarmMsg(AGVManager.agvInfo[i].Name, "lineAgv." + AGVManager.agvInfo[i].Name + ".Place", AGVManager.agvInfo[i].Place, 1));
                                }
                            }
                        }
                        catch (Exception ex)
                        {  
                            log.Error(AGVManager.agvInfo[i].Name + "上报小车运行步骤失败" + ex.Message + ex.StackTrace);
                        }
                    }
                    HttpManager.updateDeviceAlarmMsg(msglist);
                }
                catch (Exception ex)
                {
                    log.Error("AgvStateTimer_" + AGVManager.agvInfo[i].Name + ex.Message + ex.StackTrace);
                }
            }

            AgvStateInProcess = false;
        }

        /// <summary>
        /// 从节点获取任务
        /// </summary>
        /// <param name="agv_Info"></param>
        /// <returns></returns>
        public Job GetJob(Agv_Info agv_Info)
        {
            foreach (JobType jobType in AGVManager.jobTypes)
            {
                Job job = null;
                if (agv_Info.IsUse)
                    job = jobType.GetNewJob(agv_Info);
                else
                    return null;
                if (job != null)
                {
                    return job;
                }
            }
            return null;
        }

        private bool AgvCallInProcess = false;
        private void AgvCallTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (AgvCallInProcess) return;
            AgvCallInProcess = true;
            for (int i = 0; i < AGVManager.agvInfo.Count; i++)
            {
                try
                {
                    Agv_Info agv = AGVManager.agvInfo[i];
                    if (!agv.IsCon) continue;   //AGV网络连接
                    if (!agv.IsUse) continue;   //AGV是否可用

                    //Ready,Pause,Executing,Error
                    if (!AGVManager.agvInfo[i].StateID.Equals(eAGVState.Ready) && !AGVManager.agvInfo[i].StateID.Equals(eAGVState.Pause)
                        && !AGVManager.agvInfo[i].StateID.Equals(eAGVState.Executing) && !AGVManager.agvInfo[i].StateID.Equals(eAGVState.None))
                    {
                        log.Warn(string.Format("{0}不能调用 StateID={1}", AGVManager.agvInfo[i].Name, AGVManager.agvInfo[i].StateID.ToString()));
                        continue;
                    }

                    if (agv.CurJob == null)
                    {
                        Job job = GetJob(agv);
                        if (job != null)
                        {
                            agv.CurJob = job;
                        }
                    }

                    if (agv.CurJob != null)
                    {
                        agv.CurJob = agv.CurJob.Execute(agv);
                    }

                }
                catch (Exception ex)
                {
                    log.Error("AgvCall " + ex.Message + ex.StackTrace);
                }
            }

            AgvCallInProcess = false;

        }


        private bool CheckOnline(int idx)
        {
            bool rtn = MiR_API.CheckIP(AGVManager.agvInfo[idx].IP);
            if (rtn)
            {
                if (!AGVManager.agvInfo[idx].IsCon)
                {
                    AGVManager.agvInfo[idx].IsCon = true;
                    log.Info(AGVManager.agvInfo[idx].Name + " Online");
                    AgvOnline?.Invoke(idx);
                }
            }
            else
            {
                if (AGVManager.agvInfo[idx].IsCon)
                {
                    AGVManager.agvInfo[idx].IsCon = false;
                    log.Info(AGVManager.agvInfo[idx].Name + " Offline");
                    AgvOnline?.Invoke(idx);
                }
            }
            return rtn;
        }

    }
}