| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835 | using System;using System.Collections.Generic;using System.Collections.Specialized;using System.Linq;using System.Text;using Aitex.Core.RT.Event;using Aitex.Core.RT.Log;using Aitex.Core.Util;namespace Aitex.Core.RT.Routine{    public class RoutineFaildException : ApplicationException    {         public RoutineFaildException() { }        public RoutineFaildException(string message)              : base(message) { }      }    public class RoutineBreakException : ApplicationException    {        public RoutineBreakException() { }        public RoutineBreakException(string message)            : base(message) { }    }    public enum RoutineState    {        Running,        Failed,        Timeout,        Finished,    }    public class RoutineResult    {        public RoutineState Result;        public string ErrorMessage;    }    public class SeqenecRoutine    {        //timer, 计算routine时间        protected DeviceTimer counter = new DeviceTimer();        protected DeviceTimer delayTimer = new DeviceTimer();                private enum STATE        {            IDLE,                      WAIT,                  }        private int _id;         //step index        private Stack<int> _steps = new Stack<int>();        private STATE state;    //step state //idel,wait,        //loop control        private int  loop = 0;        private int  loopCount = 0;        private int  loopID = 0;           private DeviceTimer timer = new DeviceTimer();        public int LoopCounter { get { return loop; } }       // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }        //状态持续时间,单位为秒        public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }        protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };        public void Reset()        {            _id = 0;            _steps.Clear();            loop  = 0;            state = STATE.IDLE;            counter.Start(60*60*100);   //默认1小时            RoutineToken.Result = RoutineState.Running;        }        protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)        {            if (!Acitve(id))                return;            result.Result = execution();        }         #region interface        public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)         {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);                        if (bActive)            {                if (!func())                {                    return Tuple.Create(bActive, Result.FAIL);   //执行错误                }                loopID = idx;                loopCount = count;                next();                return Tuple.Create(true, Result.RUN);                 }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (++loop >= loopCount)   //Loop 结束                {                    if (!func())                    {                        return Tuple.Create(bActive, Result.FAIL);   //执行错误                    }                    loop  = 0;                    next();                    return Tuple.Create(true, Result.RUN);                }                //继续下一LOOP                next(loopID);                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);                      if (bActive)            {                if (state == STATE.IDLE)                {                    Result startRet = routine.Start();                    if (startRet == Result.FAIL)                    {                        return Tuple.Create(true, Result.FAIL);   //执行错误                    }else if (startRet == Result.DONE)                    {                        next();                        return Tuple.Create(true, Result.DONE);                    }                    state = STATE.WAIT;                }                Result ret = routine.Monitor();                if (ret == Result.DONE)                {                    next();                    return Tuple.Create(true, Result.DONE);                }                else if (ret == Result.FAIL || ret == Result.TIMEOUT)                {                    return Tuple.Create(true, Result.FAIL);                }                else                {                    return Tuple.Create(true, Result.RUN);                }            }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> ExecuteAndWaitPumpDown<T>(T id, IRoutine routine, double BasePressure)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (state == STATE.IDLE)                {                    Result startRet = routine.Start(BasePressure);                    if (startRet == Result.FAIL)                    {                        return Tuple.Create(true, Result.FAIL);   //执行错误                    }                    else if (startRet == Result.DONE)                    {                        next();                        return Tuple.Create(true, Result.DONE);                    }                    state = STATE.WAIT;                }                Result ret = routine.Monitor();                if (ret == Result.DONE)                {                    next();                    return Tuple.Create(true, Result.DONE);                }                else if (ret == Result.FAIL || ret == Result.TIMEOUT)                {                    return Tuple.Create(true, Result.FAIL);                }                else                {                    return Tuple.Create(true, Result.RUN);                }            }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (state == STATE.IDLE)                {                    foreach (var item in routines)                    {                        if (item.Start() == Result.FAIL)                            return Tuple.Create(true, Result.FAIL);                    }                    state = STATE.WAIT;                }                //wait all sub failed or completedboo                bool bFail = false;                bool bDone = true;                foreach (var item in routines)                {                    Result ret = item.Monitor();                    bDone &= (ret == Result.FAIL || ret == Result.DONE);                    bFail |= ret == Result.FAIL;                }                if (bDone)                {                    next();                    if(bFail)                        return Tuple.Create(true, Result.FAIL);                    return Tuple.Create(true, Result.DONE);                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> Check<T>(T id, Func<bool> func)   //顺序执行        {            return Check(Check(Convert.ToInt32(id), func));        }        public Tuple<bool, Result> Execute<T>(T id, Func<bool> func)   //顺序执行        {            return Check(execute(Convert.ToInt32(id), func));        }        public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue)  //Wait condition        {            return Check(wait(Convert.ToInt32(id), func, timeout));        }        public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue)  //Wait condition        {            return Check(wait(Convert.ToInt32(id), func, timeout));        }        public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = int.MaxValue)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            bool? bExecute = false;            if (bActive)            {                if (state == STATE.IDLE)                {                    if (!execute())                    {                        return Tuple.Create(bActive, Result.FAIL);   //执行错误                    }                    timer.Start(timeout);                    state = STATE.WAIT;                }                                bExecute = check();                if (bExecute == null)                {                    return Tuple.Create(bActive, Result.FAIL);    //Termianate                }                else                {                    if (bExecute.Value)       //检查Success, next                    {                        next();                        return Tuple.Create(true, Result.RUN);                        }                }                if(timer.IsTimeout())                    return Tuple.Create(true, Result.TIMEOUT);                   return Tuple.Create(true, Result.RUN);                 }            return Tuple.Create(false, Result.RUN);        }                 public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            bool? bExecute = false;            double timeout = 0;            if (bActive)            {                if (state == STATE.IDLE)                {                    timeout = time();                    if (!execute())                    {                        return Tuple.Create(true, Result.FAIL);   //执行错误                    }                    timer.Start(timeout);                    state = STATE.WAIT;                }                bExecute = check();                if (bExecute == null)                {                    return Tuple.Create(true, Result.FAIL);    //Termianate                }                    if (bExecute.Value)       //检查Success, next                    {                        next();                        return Tuple.Create(true, Result.RUN);                    }                if (timer.IsTimeout())                    return Tuple.Create(true, Result.TIMEOUT);                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (state == STATE.IDLE)                {                    rt.Start();                                   state = STATE.WAIT;                }                Result ret = rt.Monitor();                            return Tuple.Create(true, ret);            }            return Tuple.Create(false, Result.RUN);         }        //Monitor        public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            bool bCheck = false;            if (bActive)            {                if (state == STATE.IDLE)                {                    if ((func != null) && !func())                    {                        return Tuple.Create(true, Result.FAIL);                    }                    timer.Start(time);                    state = STATE.WAIT;                }                bCheck = check();                if (!bCheck)                {                    return Tuple.Create(true, Result.FAIL);    //Termianate                }                if (timer.IsTimeout())                {                    next();                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        //Delay        public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (state == STATE.IDLE)                {                    if ((func != null) && !func())                    {                        return Tuple.Create(true, Result.FAIL);                    }                                            timer.Start(time);                    state = STATE.WAIT;                }                if (timer.IsTimeout())                {                    next();                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        //先delay 再运行        public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)        {            int idx = Convert.ToInt32(id);            bool bActive = Acitve(idx);            if (bActive)            {                if (state == STATE.IDLE)                {                                       timer.Start(time);                    state = STATE.WAIT;                }                if (timer.IsTimeout())                {                    if (func != null && !func())                    {                        return Tuple.Create(true, Result.FAIL);                    }                    next();                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }#endregion        private Tuple<bool,bool> execute(int id, Func<bool> func)   //顺序执行        {            bool bActive  = Acitve(id);            bool bExecute = false;            if (bActive)            {                bExecute = func();                if (bExecute)                {                    next();                }            }            return Tuple.Create(bActive, bExecute);         }        private Tuple<bool, bool> Check(int id, Func<bool> func)   //check        {            bool bActive = Acitve(id);            bool bExecute = false;            if (bActive)            {                bExecute = func();                next();            }            return Tuple.Create(bActive, bExecute);        }        /// <summary>               /// </summary>        /// <param name="id"></param>        /// <param name="func"></param>        /// <param name="timeout"></param>        /// <returns>        ///  item1 Active        ///  item2 execute        ///  item3 Timeout        ///</returns>        private Tuple<bool,bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue)  //Wait condition        {            bool bActive  = Acitve(id);            bool bExecute = false;             bool bTimeout = false;            if (bActive)            {                if (state == STATE.IDLE)                {                    timer.Start(timeout);                    state = STATE.WAIT;                }                bExecute = func();                if (bExecute)                {                    next();                                  }                bTimeout = timer.IsTimeout();            }            return Tuple.Create(bActive, bExecute, bTimeout);          }        private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue)  //Wait condition && Check error        {            bool bActive = Acitve(id);            bool? bExecute = false;            bool bTimeout = false;            if (bActive)            {                if (state == STATE.IDLE)                {                    timer.Start(timeout);                    state = STATE.WAIT;                }                bExecute = func();                if (bExecute.HasValue && bExecute.Value)                {                    next();                }                bTimeout = timer.IsTimeout();            }            return Tuple.Create(bActive, bExecute, bTimeout);         }        /// <summary>              /// </summary>        /// <param name="value"></param>        /// <returns>        /// item1 true, return item2        /// </returns>        private Tuple<bool,Result> Check(Tuple<bool, bool> value)        {            if (value.Item1)            {                if (!value.Item2)                {                    return Tuple.Create(true, Result.FAIL);                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);        }        private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)        {            if (value.Item1)   // 当前执行            {                if (CheckTimeout(value))  //timeout                {                    return Tuple.Create(true, Result.TIMEOUT);                }                return Tuple.Create(true, Result.RUN);            }            return Tuple.Create(false, Result.RUN);          }                private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)        {            if (value.Item1)   // 当前执行            {                if (value.Item2 == null)                {                    return Tuple.Create(true, Result.FAIL);                }                else                {                    if (value.Item2 == false && value.Item3 == true)  //timeout                    {                        return Tuple.Create(true, Result.TIMEOUT);                    }                    return Tuple.Create(true, Result.RUN);                }            }            return Tuple.Create(false, Result.RUN);        }        private bool CheckTimeout(Tuple<bool, bool, bool> value)        {            return value.Item1 == true && value.Item2 == false && value.Item3 == true;        }        private bool Acitve(int id) //        {            if (_steps.Contains(id))                return false;            this._id = id;            return true;        }        private void next()        {            _steps.Push(this._id);            state = STATE.IDLE;        }        private void next(int step)   //loop        {            while(_steps.Pop() != step);                       state = STATE.IDLE;        }        public void Delay(int id, double delaySeconds)        {            Tuple<bool, Result> ret = Delay(id, () =>                {                    return true;                }, delaySeconds * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.RUN)                {                    throw (new RoutineBreakException());                }            }        }    }    public class ModuleRoutine : SeqenecRoutine    {        public string Module { get; set; }        public string Name { get; set; }        public delegate RoutineState RoutineFunc<T>(T arg);        protected void Notify(string message)        {            EV.PostInfoLog(Module, $"[{Name}] routine, {message}");        }        protected void Stop(string failReason)        {            EV.PostAlarmLog(Module, $"[{Name}] routine failed, {failReason}");        }        public void TimeDelay(int id, double time)        {            Tuple<bool, Result> ret = Delay(id, () =>                {                    Notify($"Delay {time} seconds");                    return true;                }, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.RUN)                {                    throw (new RoutineBreakException());                }            }        }        protected void ExecuteRoutine(int id, IRoutine routine)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, routine);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.RUN)                {                    throw (new RoutineBreakException());                }            }        }        protected void ExecutePumpDownRoutine(int id, IRoutine routine, double BasePressure)        {            Tuple<bool, Result> ret = ExecuteAndWaitPumpDown(id, routine, BasePressure);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw (new RoutineFaildException());                }                else if (ret.Item2 == Result.RUN)                {                    throw (new RoutineBreakException());                }            }        }        protected void PerformStep<T, T1>(T step, RoutineFunc<T1> func, T1 param1)        {            int idx = Convert.ToInt32(step);            RoutineState state = func(param1);        }    }    public class QueueRoutine    {        private Queue< IRoutine > _steps = new Queue< IRoutine >();        private  IRoutine  _currentStep = null;         public void Add(IRoutine step)        {            _steps.Enqueue(step);        }        public void Reset()        {            _steps.Clear();            _currentStep = null;        }        public void Abort()        {            if (_currentStep != null)                _currentStep.Abort();            Reset();        }        public Result Start(params object[] objs)        {            if (_steps.Count == 0)                return Result.DONE;            _currentStep = _steps.Dequeue();            return _currentStep.Start(objs);        }        public Result Monitor(params object[] objs)        {            Result ret = Result.FAIL;            if (_currentStep != null)            {                ret = _currentStep.Monitor();            }            if (ret == Result.DONE)            {                _currentStep = _steps.Count > 0 ? _steps.Dequeue() : null;                if (_currentStep != null)                {                    return _currentStep.Start(objs);                }            }             return ret;        }    }}
 |