234 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using System.Text;
 | |
| 
 | |
| namespace Project
 | |
| {
 | |
|     public partial class StateMachine
 | |
|     {
 | |
|         public DateTime UpdateTime;
 | |
|         private Boolean bLoop = true;
 | |
|         private DateTime StepStartTime;
 | |
|         private byte _messageOption;
 | |
|         private Boolean _isRun;
 | |
|         private System.Threading.Thread worker;
 | |
|         private Boolean firstRun = false;
 | |
|         public Boolean isRun { get { return _isRun; } }
 | |
|         public double Loop_ms { get; set; }
 | |
|         // private IMCResult MCResult = null;
 | |
| 
 | |
|         public StateMachine()
 | |
|         {
 | |
|             UpdateTime = DateTime.Now;
 | |
|             _messageOption = 0xFF;   //모든메세지가 오도록 한다.
 | |
|             worker = new System.Threading.Thread(new System.Threading.ThreadStart(Loop));
 | |
|             worker.IsBackground = false;
 | |
|             StepStartTime = DateTime.Parse("1982-11-23");
 | |
|             Loop_ms = 0;
 | |
|         }
 | |
| 
 | |
|         //public void attachMCResult(IMCResult item)
 | |
|         //{
 | |
|         //    MCResult = item;
 | |
|         //    if (GetMsgOpt(eMsgOpt.NORMAL))
 | |
|         //        RaiseMessage("ATTACH", string.Format("MCResult"));
 | |
|         //}
 | |
| 
 | |
|         public void Stop()
 | |
|         {
 | |
|             bLoop = false;
 | |
|             worker.Abort();
 | |
|         }
 | |
|         public void Start()
 | |
|         {
 | |
|             worker.Start();
 | |
|         }
 | |
| 
 | |
|         void Loop()
 | |
|         {
 | |
|             _isRun = true;
 | |
|             RaiseMessage("SM", "Start");
 | |
|             while (bLoop)
 | |
|             {
 | |
| 
 | |
|                 //Console.WriteLine("LOOP-START  => 11111111111   " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
 | |
| 
 | |
| 
 | |
|                 //이전업데이트타임과의 시간차를 기록한다
 | |
|                 Loop_ms = (DateTime.Now - UpdateTime).TotalMilliseconds;
 | |
| 
 | |
|                 UpdateTime = DateTime.Now;
 | |
| 
 | |
|                 //항상 작동하는 경우
 | |
|                 if (SPS != null)
 | |
|                 {
 | |
|                     //try
 | |
|                     //{
 | |
|                         SPS(this,new EventArgs());
 | |
|                     //}
 | |
|                     //catch (Exception ex)
 | |
|                     //{
 | |
|                     //    Console.WriteLine("ERROR:SM:SPS:" + ex.Message);
 | |
|                     //}
 | |
|                 }
 | |
| 
 | |
| 
 | |
| 
 | |
|                // Console.WriteLine("LOOP-START  => 2222222222   " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
 | |
| 
 | |
|                 //작동스텝이 변경되었다면 그것을 알림 처리한다.
 | |
|                 if (getNewStep != Step)
 | |
|                 {
 | |
|                     if (GetMsgOpt(eMsgOpt.STEPCHANGE))
 | |
|                         RaiseMessage("SM-STEP", string.Format("Step Changed {0} >> {1}", Step, getNewStep));
 | |
| 
 | |
|                     StepApply();
 | |
|                     firstRun = true;
 | |
|                     StepStartTime = DateTime.Now;
 | |
|                 }
 | |
|                 else firstRun = false;
 | |
| 
 | |
|                // Console.WriteLine("LOOP-START  => 3333333333   " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
 | |
| 
 | |
|                 //동작중에 발생하는 이벤트
 | |
|                 if (Running != null)
 | |
|                 {
 | |
| 
 | |
|                     //try
 | |
|                     //{
 | |
|                         Running(this,new RunningEventArgs(Step, firstRun, StepRunTime));
 | |
|                     //}
 | |
|                     //catch (Exception ex)
 | |
|                     //{
 | |
|                     //    //오류보고는 3초에 한번씩 동작한다
 | |
|                     //    if(Pub.GetVarRunTime(eVarTime.SMRUNERROR).TotalSeconds > 3)
 | |
|                     //    {
 | |
|                     //        Pub.SetVarTime(eVarTime.SMRUNERROR, DateTime.Now);
 | |
|                     //        Pub.log.AddE("상태머신 RUN 오류:" + ex.Message);
 | |
|                     //    }   
 | |
|                     //}
 | |
|                 }
 | |
| 
 | |
|                 System.Threading.Thread.Sleep(1);
 | |
| 
 | |
|                // Console.WriteLine("LOOP-END  =>  4444444444444  " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
 | |
| 
 | |
|             }
 | |
|             _isRun = false;
 | |
|             if (GetMsgOpt(eMsgOpt.NORMAL)) RaiseMessage("SM", "Stop");
 | |
|         }
 | |
| 
 | |
|        
 | |
| 
 | |
|         eSMStep prebackupstepo = eSMStep.NOTSET;
 | |
|         eSMStep prebackupstepn = eSMStep.NOTSET;
 | |
|         public void PushStep()
 | |
|         {
 | |
|             prebackupstepo = OldStep;
 | |
|             prebackupstepn = _step;
 | |
|         }
 | |
|         public void PopStep()
 | |
|         {
 | |
|             if (prebackupstepn != eSMStep.NOTSET)
 | |
|             {
 | |
|                 _step = prebackupstepn;
 | |
|                 OldStep = prebackupstepo;
 | |
|                 prebackupstepn = eSMStep.NOTSET;
 | |
|             }
 | |
|         }
 | |
|         /// <summary>
 | |
|         /// 상태머신의 작동상태
 | |
|         /// </summary>
 | |
|         public eSMStep Step { get { return _step; } }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 상태머신값을 숫자로 반환 합니다. (20이하는 시스템상태이고 그 이상은 사용자 상태)
 | |
|         /// </summary>
 | |
|         public byte StepValue
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return (byte)this._step;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void setNewStep(eSMStep newstep_, Boolean force = false)
 | |
|         {
 | |
|             if (Step != newstep_)   //현재스텝과 새로운 스텝이 다른경우
 | |
|             {
 | |
|                 if (NewStep != newstep_)
 | |
|                 {
 | |
|                     if (force == false && NewStep == eSMStep.EMERGENCY && newstep_ != eSMStep.RESET)
 | |
|                     {
 | |
|                         //스텝을 변경해야하는데. 예약된 스텝이 비상정지라면 처리하지 않는다
 | |
|                         RaiseMessage("SM-STEP", string.Format("비상정지가 예약되어 있으므로 이 스텝({0})은 취소 됩니다", newstep_));
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         //바뀌도록 예약을 한다.
 | |
|                         NewStep = newstep_;
 | |
|                         if (GetMsgOpt(eMsgOpt.STEPCHANGE))
 | |
|                             RaiseMessage("SM-STEP", string.Format("Step Reserve {0} -> {1}", Step, NewStep));
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     //예약은 되어있는데 아직 바뀐것은 아니다.
 | |
|                     if (GetMsgOpt(eMsgOpt.STEPCHANGE))
 | |
|                         RaiseMessage("SM-STEP", string.Format("Step Already Reserve {0} -> {1}", Step, NewStep));
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         public eSMStep getNewStep
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return NewStep;
 | |
|             }
 | |
|         }
 | |
|         private eSMStep NewStep = eSMStep.NOTSET;
 | |
|         public eSMStep OldStep = eSMStep.NOTSET; //171214
 | |
|         private eSMStep _step;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// newstep 의 값을 step 에 적용합니다.
 | |
|         /// </summary>
 | |
|         private void StepApply()
 | |
|         {
 | |
|             var ostep = _step;
 | |
|             OldStep = _step; _step = NewStep;
 | |
|             if (StepChanged != null) StepChanged(this, new StepChangeEventArgs(ostep, _step));
 | |
|         }    //171214
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 메세지 출력옵션을 변경 합니다.
 | |
|         /// </summary>
 | |
|         /// <param name="opt"></param>
 | |
|         /// <param name="value"></param>
 | |
|         public void SetMsgOpt(eMsgOpt opt, Boolean value)
 | |
|         {
 | |
|             byte pos = (byte)opt;
 | |
|             if (value)
 | |
|                 _messageOption = (byte)(_messageOption | (1 << pos));
 | |
|             else
 | |
|                 _messageOption = (byte)(_messageOption & ~(1 << pos));
 | |
|         }
 | |
|         public void SetMegOptOn() { _messageOption = 0xFF; }
 | |
|         public void SetMsgOptOff() { _messageOption = 0; }
 | |
|         public Boolean GetMsgOpt(eMsgOpt opt)
 | |
|         {
 | |
|             byte pos = (byte)opt;
 | |
|             return (_messageOption & (1 << pos)) > 0;
 | |
|         }
 | |
|         public TimeSpan StepRunTime
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (StepStartTime.Year == 1982) return new TimeSpan(0);
 | |
|                 else return DateTime.Now - StepStartTime;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | 
