2023-04-13 11:51:03 +08:00
|
|
|
using System;
|
2024-01-08 16:33:45 +08:00
|
|
|
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;
|
2024-01-08 16:33:45 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-01-08 16:33:45 +08:00
|
|
|
|
|
|
|
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;
|
2024-01-09 10:05:25 +08:00
|
|
|
|
|
|
|
DATA.Subscribe($"{ModuleHelper.GetDiagnosisPath(ModuleName.System)}.OverallMonitorCostMs", () => _overallMonitorCostMs);
|
|
|
|
DATA.Subscribe($"{ModuleHelper.GetDiagnosisPath(ModuleName.System)}.OverallMonitorCnt", () => _overallMonitorCnt);
|
|
|
|
DATA.Subscribe($"{ModuleHelper.GetDiagnosisPath(ModuleName.System)}.OverallMonitorInvMs", () => _overallMonitorInvMs);
|
2024-01-08 16:33:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2024-01-08 16:33:45 +08:00
|
|
|
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++;
|
2024-01-09 10:05:25 +08:00
|
|
|
_overallMonitorCnt %= 100;
|
2024-01-08 16:33:45 +08:00
|
|
|
|
|
|
|
_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)
|
|
|
|
{
|
2024-01-08 16:33:45 +08:00
|
|
|
Running = false;
|
2023-04-13 11:51:03 +08:00
|
|
|
LOG.Error("Device Run exception", ex);
|
|
|
|
}
|
2024-01-08 16:33:45 +08:00
|
|
|
Running = true;
|
2023-04-13 11:51:03 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool fReset(object[] objs)
|
|
|
|
{
|
|
|
|
mgr.Reset();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|