LineRunMonitor.cs 6.2 KB
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace DeviceLibrary
{
    public class LineRunMonitor : ISafetyDevice
    {
        Timer lineTimer = null;
        Dictionary<string, DateTime> linrunlist = new Dictionary<string, DateTime>();
        string Name;
        ushort LineIO;
        ushort LineRevIO;
        int Rev_type = 0;
        bool isIOon = false;
        public LineRunMonitor(string name, ushort io, ushort rev_io=0, int rev_type=0) {
            Name = name;
            LineIO = io;
            LineRevIO = rev_io;
            Rev_type = rev_type;
            LineInit();
            SafetyDevice.AddDevice(this);
        }
        //public bool Reversal { get; set; }
        void LineInit()
        {
            if (lineTimer == null)
            {
                lineTimer = new Timer(100);
                lineTimer.Elapsed += LineTimer_Elapsed;
                lineTimer.Start();
                GC.KeepAlive(lineTimer);
            }
            if (!lineTimer.Enabled)
                lineTimer.Enabled = true;
        }

        private void LineTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (canStopLine(out _) && isIOon)//(DOValue(LineIO).Equals(IO_VALUE.HIGH) || DOValue(LineRevIO).Equals(IO_VALUE.HIGH)))
            {
                IOSTOP();
                LogUtil.info(Name + $" 线体管理器 停止线体.");
            }
        }

        private void DOMove(ushort LineIO, IO_VALUE iovalue)
        {
            IOManager.WriteSingleDO("", 0x00, LineIO, iovalue);
        }

        private object DOValue(ushort LineIO)
        {
            return IOManager.GetDOValue("", 0x00, LineIO);
        }

        DateTime pauseTime= DateTime.MinValue;
        public void Pause() {
            if (lineTimer.Enabled)
            {
                lineTimer.Enabled = false;
                pauseTime = DateTime.Now;
                IOSTOP();
                if (linrunlist.Count>0)
                    LogUtil.info(Name + $" 线体管理器 暂停线体.");
            }
        }
        public void Resume() {

            if (pauseTime != DateTime.MinValue)
            {
                lock (linrunlist)
                {
                    if (linrunlist.Count > 0)
                    {
                        foreach (var k in linrunlist.Keys.ToArray())
                        {
                            if (linrunlist.ContainsKey(k))
                                linrunlist[k] += DateTime.Now - pauseTime;
                        }
                        IORUN();
                    }
                }
                pauseTime = DateTime.MinValue;
                lineTimer.Enabled = true;
                if (linrunlist.Count > 0)
                    LogUtil.info(Name + $" 线体管理器 恢复运行线体.");
            }
           
        }

        void IORUN() {
            
            if (Reversal)
            {
                if (Rev_type==0)
                    DOMove(LineIO, IO_VALUE.LOW);
                else
                    DOMove(LineIO, IO_VALUE.HIGH);
                DOMove(LineRevIO, IO_VALUE.HIGH);
            }
            else
            {
                DOMove(LineRevIO, IO_VALUE.LOW);
                DOMove(LineIO, IO_VALUE.HIGH);
            }
            isIOon = true;
        }
        void IOSTOP()
        {
            isIOon = false;
            DOMove(LineIO, IO_VALUE.LOW);
            DOMove(LineRevIO, IO_VALUE.LOW);
        }
        bool Reversal = false;
        /// <summary>
        /// 控制线体运转
        /// </summary>
        /// <param name="id">需求方标识</param>
        /// <param name="Reversal">是否反转</param>
        /// <param name="seconds">秒数</param>
        public void LineRun(string id,bool reversal, int seconds, string parentname = "")
        {
            LineInit();
            
            lock (linrunlist)
            {
                this.Reversal = reversal;
                IORUN();
                if (!string.IsNullOrEmpty(id) && seconds > 0)
                {
                    if (linrunlist.ContainsKey(id))
                        linrunlist[id] = DateTime.Now.AddSeconds(seconds);
                    else
                    {
                        linrunlist.Add(id, DateTime.Now.AddSeconds(seconds));
                    }
                    LogUtil.info(Name + $" 线体管理器 {id},{parentname} 请求链条运行 {seconds}秒.");
                    linrunlist.Values.ToList().ForEach(l => { LogUtil.info(Name + " " + l); });
                }
            }
        }
        public void LineStop(string id, string parentname = "")
        {
            lock (linrunlist)
            {
                if (!string.IsNullOrEmpty(id))
                {
                    if (linrunlist.ContainsKey(id))
                        linrunlist.Remove(id);
                    LogUtil.info(Name + $" 线体管理器 {id},{parentname} 请求立刻停止线体.");
                }
            }

            if (!canStopLine(out string msg))
                LogUtil.info(Name + $" {Name}");

            if (!lineTimer.Enabled)
                lineTimer.Enabled = true;
            //    IOMove(IO_Type.Line_Run, IO_VALUE.LOW);
        }
        bool canStopLine(out string msg)
        {
            msg = "";
            bool canStop = true;
            lock (linrunlist)
            {
                foreach (var x in linrunlist.ToList())
                {
                    if (x.Value > DateTime.Now)
                    {
                        canStop = false;
                        msg = Name + $" 线体管理器 {x.Key} 不允许停止线体 需求停止时间 {x.Value.ToString()}.";
                        //LogUtil.info(Name + $" {x.Key} 不允许停止线体 需求停止时间 {x.Value.ToString()}.");
                    }
                    else
                    {
                        LogUtil.info(Name + $" 线体管理器 {x.Key} 请求时间已过期,删除.");
                        linrunlist.Remove(x.Key);

                    }
                }
            }
            return canStop;
        }
    }
}