123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using Aitex.Core.RT.Fsm;
- using Aitex.Core.RT.IOCore;
- using Aitex.Core.Util;
- using Aitex.Core.RT.Log;
- namespace Aitex.Core.RT.PLC
- {
- public class PLCEntityT<T, TBuffer, TInput, TOutput> : Entity
- where T : IDataDevice, new()
- where TBuffer : IDataBuffer<TInput, TOutput>, new()
- where TInput : struct
- where TOutput : struct
- {
- private T device = default(T);
- private Dictionary<string, TBuffer> _buffers = new Dictionary<string,TBuffer>();
- //retry
- private int error = 0;
- private int retryWaitTime = 100;
- private int retryTimes = 10;
- private R_TRIG errTrig = new R_TRIG();
-
- public enum STATE
- {
- INIT,
- RUNNING,
- ERROR, //
- };
- public enum MSG
- {
- INIT,
- ERROR,
- RECOVERY,
- RESET,
- };
- public PLCEntityT()
- {
- Running = false;
- device = new T();
- foreach (var type in device.GetTypes())
- {
- _buffers[type] = new TBuffer();
- }
- fsm = new StateMachine<PLCEntityT<T, TBuffer, TInput, TOutput>>("PLC", (int)STATE.INIT, 100);
- EnterExitTransition<STATE, MSG>(STATE.INIT, null, MSG.INIT, null);
-
- Transition(STATE.INIT, MSG.INIT, OpenDevice, STATE.RUNNING);
- Transition(STATE.RUNNING, FSM_MSG.TIMER, Run, STATE.RUNNING);
- Transition(STATE.RUNNING, MSG.RESET, Reset, STATE.RUNNING);
-
- Transition(STATE.ERROR, FSM_MSG.TIMER, Retry, STATE.RUNNING);
- Transition(STATE.ERROR, MSG.RECOVERY, Recovery, STATE.INIT);
- AnyStateTransition(MSG.ERROR, Error, STATE.ERROR);
- errTrig.CLK = false;
-
- }
- #region FSM Function
- private bool OpenDevice(object[] objs)
- {
- Running = false;
- if (!device.Open())
- {
- PostMsg<MSG>(MSG.ERROR);
- return false; //don't change state
- }
-
- return true;
- }
- private bool Run(object[] objs)
- {
- try
- {
- foreach (var type in device.GetTypes())
- {
- try
- {
- if (!device.IsOpen(type))
- {
- device.Open(type);
- continue;
- }
- object obj = device.Read<TInput>(type);
- if (obj == null)
- {
- throw new Exception();
- }
- _buffers[type].Input = (TInput)obj;
- Singleton<IOGroupManager>.Instance.Update(type, _buffers[type]);
- if (device.Write(type, _buffers[type].Output))
- {
- errTrig.CLK = false;
- error = 0;
- }
- }
- catch (Exception ex)
- {
- device.Close(type);
- LOG.Write(ex);
- }
-
- }
- }
- catch (Exception ex)
- {
- errTrig.CLK = true;
- if (errTrig.Q)
- {
- LOG.Write(ex);
- }
- }
- Running = true;
- return true;
- }
-
- private bool Error(object[] objs)
- {
- //add log
- if (error++ > retryTimes || !device.IsOpened)
- {
- PostMsg(MSG.RECOVERY);
- }
- return true;
- }
- private bool Retry(object[] objs)
- {
- //add log
- int elapsed = fsm.ElapsedTime;
- if (elapsed > retryWaitTime)
- {
- return true;
- }
- return false;
- }
- //关闭连接
- private bool Recovery(object[] objs)
- {
- device.Close();
- return true;
- }
- private bool Reset(object[] objs)
- {
- errTrig.RST = true;
- return true;
- }
-
- #endregion
- }
- }
|