LiftMonitor.cs 10.9 KB
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DeviceLibrary
{
    public class LiftMonitor : ISafetyDevice
    {
        /// <summary>
        /// 关闭端延时
        /// </summary>
        public int DownOverTimeMS = 0;
        public int UpOverTimeMS = 0;
        public bool SlowAftPause = false;
        string up;
        string down;
        string saftylight;
        string axisbreak;
        public AxisBean axisBean;
        int upspeed;
        int downspeed;
        int StrokeLength = 270000;
        MoveInfo moveInfo1;
        bool paused = false;
        public LiftMonitor(string _up, string _down, string _saftylight, string _break, AxisBean _axisBean, int _StrokeLength, int _upspeed, int _downspeed = 0, string name = "升降机构")
        {
            moveInfo1 = new MoveInfo(name, false);
            up = _up;
            down = _down;
            saftylight = _saftylight;
            axisBean = _axisBean;
            upspeed = _upspeed;
            axisbreak = _break;
            downspeed = _downspeed;
            StrokeLength = _StrokeLength;
            if (downspeed == 0)
            {
                downspeed = upspeed;
            }
            SafetyDevice.AddDevice(this);
        }

        public void UpdateParam(int length, int upSpeed, int downSpeed = 0)
        {
            StrokeLength = length;
            upspeed = upSpeed;
            if (downspeed == 0)
            {
                downspeed = upspeed;
            }
        }
        public void ClearAlarm()
        {

        }
        public bool isAtTOP
        {
            get
            {
                return IOManager.IOValue(up.ToString()).Equals(IO_VALUE.HIGH);
            }
        }
        public bool isAtBOTTOM
        {
            get
            {
                return IOManager.IOValue(down.ToString()).Equals(IO_VALUE.HIGH);
            }
        }
        public void LiftUp(MoveInfo moveInfo)
        {

            if (moveInfo == null)
                moveInfo = moveInfo1;
            if (IOManager.IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
            {
                moveInfo.log($"急停未解除");
                return;
            }
            double speed = (double)upspeed;
            if (paused && SlowAftPause)
            {
                speed = speed / 3.0;
                moveInfo.log($"上一次有暂停,速度降为{speed}");
            }
            paused = false;
            if (IOManager.IOValue(up.ToString()).Equals(IO_VALUE.HIGH))
            {
                moveInfo.log($"{axisBean.AxisName},已在位置,无需上升");
                return;
            }
            if (!axisBean.IsServeoOn)
                axisBean.Open(true, out string msg);
            if (!string.IsNullOrEmpty(axisbreak))
            {
                IOManager.IOMove(axisbreak, IO_VALUE.HIGH);
                Thread.Sleep(200);
            }
            axisBean.RelMove(StrokeLength, speed);
            DateTime d = DateTime.Now;
            moveInfo.log($"{axisBean.AxisName},LiftUp");
            var wr = WaitResultInfo.WaitAction(new Func<WaitResultInfo, bool>(WaitUp), $"等待顶升[{axisBean.Config.Explain}]机构上升");
            if (moveInfo != null)
                moveInfo.WaitList.Add(wr);
            Task.Run(() =>
            {
                while (!IOManager.IOValue(up.ToString()).Equals(IO_VALUE.HIGH))
                {
                    Task.Delay(15).Wait();
                    if (paused)
                    {
                        paused = false;
                        return;
                    }
                    if (IOManager.IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
                    {
                        moveInfo.log("设备急停");
                        emergencyStop();
                        return;
                    }
                    if (!string.IsNullOrEmpty(saftylight) && IOManager.IOValue(saftylight).Equals(IO_VALUE.LOW) && IOManager.IOValue(down.ToString()).Equals(IO_VALUE.LOW))
                    {
                        moveInfo.log($"{saftylight}触发停止");
                        Pause();
                        return;
                    }
                }
                moveInfo1.WaitList.Clear();
                moveInfo.WaitList.Remove(wr);
                if (UpOverTimeMS > 0)
                    Task.Delay(UpOverTimeMS).Wait();
                axisBean.SuddenStop();
                if (!string.IsNullOrEmpty(axisbreak))
                {
                    IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                    axisBean.ServoOff();
                }

                var t = (DateTime.Now - d).TotalSeconds;
                moveInfo.log($"{axisBean.AxisName},上升到位,s:{t}");
            });
        }
        bool WaitUp(WaitResultInfo w)
        {
            if ((DateTime.Now - LastResumeTime).TotalSeconds < ResumeWaitTimeSec)
                return false;
            if (IOManager.IOValue(up.ToString()).Equals(IO_VALUE.HIGH))
            {
                if (UpOverTimeMS > 0)
                    Task.Delay(UpOverTimeMS).Wait();
                axisBean.SuddenStop();

                if (!string.IsNullOrEmpty(axisbreak))
                {
                    IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                    axisBean.ServoOff();
                }
                return true;
            }

            if (!axisBean.IsBusy)
            {
                LogUtil.info("恢复继续上升");
                LiftUp(null);
            }
            return false;
        }
        public void LiftDown(MoveInfo moveInfo)
        {
            if (moveInfo == null)
                moveInfo = moveInfo1;
            if (IOManager.IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
            {
                moveInfo.log($"急停未解除");
                return;
            }
            double speed = (double)downspeed;
            if (paused && SlowAftPause)
            {
                speed = speed / 3.0;
                moveInfo.log($"上一次有暂停,速度降为{speed}");
            }
            paused = false;
            if (IOManager.IOValue(down.ToString()).Equals(IO_VALUE.HIGH))
            {
                moveInfo.log($"{axisBean.AxisName},已在位置,无需下降");
                return;
            }
            if (!axisBean.IsServeoOn)
                axisBean.Open(true, out string msg);
            if (!string.IsNullOrEmpty(axisbreak))
            {
                IOManager.IOMove(axisbreak, IO_VALUE.HIGH);
                Thread.Sleep(200);
            }
            axisBean.RelMove(-StrokeLength, speed);
            DateTime d = DateTime.Now;
            moveInfo.log($"{axisBean.AxisName},LiftDown");
            var wr = WaitResultInfo.WaitAction(new Func<WaitResultInfo, bool>(WaitDown), $"等待顶升[{axisBean.Config.Explain}]机构下降");
            if (moveInfo != null)
                moveInfo.WaitList.Add(wr);

            Task.Run(() =>
            {
                while (!IOManager.IOValue(down.ToString()).Equals(IO_VALUE.HIGH))
                {
                    Task.Delay(15).Wait();
                    if (paused)
                    {
                        paused = false;
                        return;
                    }
                    if (IOManager.IOValue(IO_Type.SuddenStop_BTN).Equals(IO_VALUE.LOW))
                    {
                        LogUtil.info("设备急停");
                        emergencyStop();
                        return;
                    }
                    if (!string.IsNullOrEmpty(saftylight) && IOManager.IOValue(saftylight).Equals(IO_VALUE.LOW))
                    {
                        moveInfo.log($"{saftylight}触发停止");
                        Pause();
                        return;
                    }
                }
                moveInfo1.WaitList.Clear();
                moveInfo.WaitList.Remove(wr);

                if (DownOverTimeMS > 0)
                    Task.Delay(DownOverTimeMS).Wait();
                axisBean.SuddenStop();
                if (!string.IsNullOrEmpty(axisbreak))
                {
                    IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                    axisBean.ServoOff();
                }
                var t = (DateTime.Now - d).TotalSeconds;
                moveInfo.log($"{axisBean.AxisName},下降到位,s:{t}");
            });
        }
        bool WaitDown(WaitResultInfo w)
        {
            if ((DateTime.Now - LastResumeTime).TotalSeconds < ResumeWaitTimeSec)
                return false;
            if (IOManager.IOValue(down.ToString()).Equals(IO_VALUE.HIGH))
            {
                if (DownOverTimeMS > 0)
                    Task.Delay(DownOverTimeMS).Wait();
                axisBean.SuddenStop();

                if (!string.IsNullOrEmpty(axisbreak))
                {
                    IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                    axisBean.ServoOff();
                }
                return true;
            }

            if (!axisBean.IsBusy)
            {
                LogUtil.info("恢复继续下降");
                LiftDown(null);
            }
            return false;
        }
        void emergencyStop()
        {
            paused = true;
            axisBean.SuddenStop();
            if (!string.IsNullOrEmpty(axisbreak))
            {
                IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                axisBean.ServoOff();
            }
        }
        public void Pause()
        {
            // if (!isDoorClose())
            {
                paused = true;
                axisBean.SuddenStop();
                if (!string.IsNullOrEmpty(axisbreak))
                {
                    IOManager.IOMove(axisbreak, IO_VALUE.LOW);
                    axisBean.ServoOff();
                }
            }
        }
        DateTime LastResumeTime = DateTime.Now;
        public int ResumeWaitTimeSec = 0;
        public void Resume()
        {
            ResumeSingle();
        }
        public void ResumeSingle()
        {
            LastResumeTime = DateTime.Now;
            try
            {
                if (moveInfo1.WaitList.Count > 0)
                {
                    if (moveInfo1.WaitList[0].WaitType == WaitEnum.W013_Action)
                    {
                        var wt = moveInfo1.WaitList[0];
                        for (int i = 0; i < 100; i++)
                        {
                            var w = wt.Action?.Invoke(moveInfo1.WaitList[0]);
                            if (w == null)
                                return;
                            if (w.Value)
                                break;
                            Task.Delay(100).Wait();
                        }
                    }
                }
            }
            catch { }
        }
    }
}