Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/Aitex/Core/RT/Device/DeviceEntityT.cs

151 lines
4.1 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Diagnostics;
using Aitex.Core.RT.DataCenter;
2023-04-13 11:51:03 +08:00
using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
2023-04-13 11:51:03 +08:00
namespace Aitex.Core.RT.Device
{
public abstract class DeviceEntityT<T> : Entity, IEntity where T : class, IDeviceManager, new()
{
public enum STATE
{
INIT = 0,
RUNNING = 1,
WAIT_RESET = 2,
ERROR = 3
}
public enum MSG
{
INIT = 0,
ERROR = 1,
WAIT_RESET = 2,
RESET = 3
}
protected const int MIN_MONITOR_INV_MS = 0;
protected const int MAX_MONITOR_INV_MS = 5000;
protected const int DEF_MONITOR_INV_MS = 100;
private readonly R_TRIG _rTrigOverallMonitorTooSlow = new();
private readonly R_TRIG _rTrigOverallMonitorInvTooLong = new();
private readonly DeviceTimer _tmrMonitorPeriod = new();
private readonly Stopwatch _swMonitorCost = new ();
private readonly Stopwatch _swMonitorInv = new ();
private int _overallMonitorCostMs = 0;
private int _overallMonitorCnt = 0;
private int _overallMonitorInvMs = 0;
2023-04-13 11:51:03 +08:00
private T mgr = null;
public bool IsWaitReset => fsm.State == 2;
public DeviceEntityT()
{
base.Running = false;
fsm = new StateMachine<DeviceEntityT<T>>("DeviceLayer", 0, 50);
EnterExitTransition<STATE, MSG>(STATE.INIT, null, MSG.INIT, null);
Transition(STATE.INIT, MSG.INIT, fInit, STATE.RUNNING);
Transition(STATE.RUNNING, FSM_MSG.TIMER, fRun, STATE.RUNNING);
Transition(STATE.RUNNING, MSG.RESET, fReset, STATE.RUNNING);
mgr = Singleton<T>.Instance;
DATA.Subscribe($"{ModuleName.System}.{ModuleName.Diagnosis}.OverallMonitorCostMs", () => _overallMonitorCostMs);
DATA.Subscribe($"{ModuleName.System}.{ModuleName.Diagnosis}.OverallMonitorCnt", () => _overallMonitorCnt);
DATA.Subscribe($"{ModuleName.System}.{ModuleName.Diagnosis}.OverallMonitorInvMs", () => _overallMonitorInvMs);
Debug.Assert(MIN_MONITOR_INV_MS < DEF_MONITOR_INV_MS, "const variable definition error.");
Debug.Assert(MAX_MONITOR_INV_MS > DEF_MONITOR_INV_MS, "const variable definition error.");
MonitorPeriodMs = DEF_MONITOR_INV_MS;
_tmrMonitorPeriod.Start(MonitorPeriodMs);
}
public virtual int MonitorPeriodMs
{
get;
private set;
}
public void ChangeMinMonitorPeriodMs(int period)
{
if (period == MonitorPeriodMs)
return;
var _ssPeriod = MIN_MONITOR_INV_MS;
if (period < MIN_MONITOR_INV_MS)
MonitorPeriodMs = MIN_MONITOR_INV_MS;
else if (period > MAX_MONITOR_INV_MS)
MonitorPeriodMs = MAX_MONITOR_INV_MS;
else
MonitorPeriodMs = period;
LOG.Info($"{this}.{nameof(MonitorPeriodMs)} change from {_ssPeriod}ms to {MonitorPeriodMs}ms");
2023-04-13 11:51:03 +08:00
}
public bool Check(int msg, out string reason, params object[] args)
{
reason = "";
return true;
}
private bool fInit(object[] objs)
{
return true;
}
private bool fRun(object[] objs)
{
try
{
if (_tmrMonitorPeriod.IsTimeout())
{
_swMonitorInv.Stop();
_overallMonitorInvMs = (int)_swMonitorInv.Elapsed.TotalMilliseconds;
_swMonitorCost.Reset();
_swMonitorCost.Start();
_tmrMonitorPeriod.Start(MonitorPeriodMs);
mgr.Monitor();
_swMonitorCost.Stop();
_overallMonitorCostMs = (int)_swMonitorCost.Elapsed.TotalMilliseconds;
_overallMonitorCnt++;
_overallMonitorCnt %= 100;
_swMonitorInv.Reset();
_swMonitorInv.Start();
}
_rTrigOverallMonitorTooSlow.CLK = _overallMonitorCostMs > 3000;
if(_rTrigOverallMonitorTooSlow.Q)
LOG.Warning($"Device Manager overall monitor too slow, costs {_overallMonitorCostMs}ms where the limit is 3000ms");
_rTrigOverallMonitorInvTooLong.CLK = _overallMonitorInvMs > MAX_MONITOR_INV_MS * 1.5;
if(_rTrigOverallMonitorInvTooLong.Q)
LOG.Warning($"Device Manager overall monitor interval is too long, costs {_overallMonitorInvMs}ms where the limit is {MAX_MONITOR_INV_MS * 1.5}ms");
2023-04-13 11:51:03 +08:00
}
catch (Exception ex)
{
Running = false;
2023-04-13 11:51:03 +08:00
LOG.Error("Device Run exception", ex);
}
Running = true;
2023-04-13 11:51:03 +08:00
return true;
}
private bool fReset(object[] objs)
{
mgr.Reset();
return true;
}
}
}