IOMonitor.cs 4.2 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;
using System.Timers;

namespace DeviceLibrary
{
    public class IOMonitor
    {
        static List<IOMonitorStrut> iOMonitorStruts = new List<IOMonitorStrut>();
        readonly static System.Timers.Timer T1 = new System.Timers.Timer();
        static IOMonitor() {
            Thread.Sleep(5000);
            T1.Interval = 30;
            T1.Elapsed += T1_Elapsed;
            T1.AutoReset = true;
            T1.Start();
        }
        ~IOMonitor()
        {
            T1.Stop();
        }
        private static void T1_Elapsed(object sender, ElapsedEventArgs e)
        {
            foreach (var iOMonitorStrut in iOMonitorStruts)
            {
                var current_iovalue = IOManager.IOValue(iOMonitorStrut.ioType, iOMonitorStrut.Config);
                var timediff = new TimeSpan(DateTime.Now.Ticks - iOMonitorStrut.lastFireTime);

                if (iOMonitorStrut.last_iO_VALUE == IO_VALUE.None) {
                    iOMonitorStrut.last_iO_VALUE = current_iovalue;
                    continue;
                }

                //LogUtil.OutputDebugString($"IOMonitor: {timediff.TotalMilliseconds},{iOMonitorStrut.Interval},last_iO_VALUE:{iOMonitorStrut.last_iO_VALUE},IOVALUE:{current_iovalue},Need:{iOMonitorStrut.iO_VALUE}");

                if (timediff.TotalMilliseconds > iOMonitorStrut.Interval && iOMonitorStrut.last_iO_VALUE != current_iovalue && current_iovalue== iOMonitorStrut.iO_VALUE)
                {
                    iOMonitorStrut.deboundCount += 30;

                    if (iOMonitorStrut.deboundCount > iOMonitorStrut.debound)
                    {
                        iOMonitorStrut.last_iO_VALUE = current_iovalue;
                        iOMonitorStrut.lastFireTime = DateTime.Now.Ticks;
                        iOMonitorStrut.deboundCount = 0;
                        LogUtil.info($"IOMonitor Fire:{iOMonitorStrut.ioType} , value:{iOMonitorStrut.iO_VALUE}");
                        iOMonitorStrut.a();
                    }
                }
                else if (iOMonitorStrut.last_iO_VALUE == current_iovalue)
                {
                    iOMonitorStrut.deboundCount = 0;
                }else
                    iOMonitorStrut.last_iO_VALUE = current_iovalue;
            }

        }

        public static void RegisterIO(string ioType, DeviceConfig Config, IO_VALUE iO_VALUE, Action a, int Interval=5000,int debound=500) {

            IOMonitorStrut iOMonitorStrut = new IOMonitorStrut()
            {
                ioType = ioType,
                Config = Config,
                iO_VALUE= iO_VALUE,
                a=a,
                Interval= Interval,
                debound= debound
            };
            iOMonitorStruts.Add(iOMonitorStrut);
        }
        static Dictionary<string, long> IODebounddict = new Dictionary<string, long>();
        public static bool IODebound(string ioType, DeviceConfig Config, IO_VALUE iO_VALUE, int debound = 1000)
        {
            long LastStateTick;
            if (IODebounddict.ContainsKey(ioType))
                LastStateTick = IODebounddict[ioType];
            else {
                LastStateTick = DateTime.Now.Ticks;
                IODebounddict.Add(ioType, LastStateTick);
            }

            var current_iovalue = IOManager.IOValue(ioType, Config);
            if (current_iovalue != iO_VALUE)
            { 
                LastStateTick = DateTime.Now.Ticks;
                return false;
            }
            var timediff = new TimeSpan(DateTime.Now.Ticks - LastStateTick).TotalMilliseconds;
            if (timediff > debound) {
                return true;
            }
            return false;
        }
        class IOMonitorStrut {
            public string ioType;
            public DeviceConfig Config;
            public IO_VALUE iO_VALUE;
            public IO_VALUE last_iO_VALUE= IO_VALUE.None;
            public Action a;
            public int Interval;
            public long lastFireTime=DateTime.Now.Ticks;
            public int debound;
            public int deboundCount=0;
            public long LastStateTick = 0;
        }
    }
}