Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../Devices/IoHeartBeat.cs

143 lines
3.7 KiB
C#
Raw Normal View History

using Aitex.Core.RT.Event;
2023-04-13 11:51:03 +08:00
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
2023-04-13 11:51:03 +08:00
using Aitex.Core.Util;
using System;
using System.Threading.Tasks;
using System.Xml;
namespace Aitex.Core.RT.Device.Devices
{
internal class IoHeartBeat : BaseDevice, IDevice
2023-04-13 11:51:03 +08:00
{
public float Feedback
{
get
{
if (_ai != null)
{
return _isFloatAioType ? _ai.FloatValue : _ai.Value;
}
return 0;
}
}
public float SetPoint
{
get
{
if (_ao != null)
{
return _isFloatAioType ? _ao.FloatValue : _ao.Value;
}
return 0;
}
set
{
if (_ao != null)
{
if (_isFloatAioType)
_ao.FloatValue = value;
else
_ao.Value = (short)value;
}
}
}
//IO
private AIAccessor _ai = null;
2023-04-13 11:51:03 +08:00
private AOAccessor _ao = null;
private bool _isFloatAioType = false;
private readonly DeviceTimer _timHeartBeatOfRange = new();
private readonly R_TRIG _trigHeartBeatError = new();
2023-04-13 11:51:03 +08:00
private short _counter = 0;
private PeriodicJob _thread;
2023-04-13 11:51:03 +08:00
private bool _isModuleInstalled;
2023-04-13 11:51:03 +08:00
public IoHeartBeat(string module, XmlElement node, string ioModule = "")
{
base.Module = module;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
_ai = ParseAiNode("ai", node, ioModule);
_ao = ParseAoNode("ao", node, ioModule);
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
}
public bool Initialize()
{
_thread = new PeriodicJob(1000, OnTimer, "PLC Write Thread", false);
_isModuleInstalled= SC.SafeGetValue($"System.SetUp.Is{Module}Installed", false);
2023-04-13 11:51:03 +08:00
//防止UI没启动就进行EV.Post
Task.Delay(1000 * 30).ContinueWith((a) => _thread.Start());
2023-04-13 11:51:03 +08:00
return true;
}
public bool OnTimer()
{
try
{
if (!_isModuleInstalled)//模块未安装直接退出
return true;
if (Feedback != SetPoint && _timHeartBeatOfRange.IsIdle())//检测值是否相等
_timHeartBeatOfRange.Start(1000 * 10);
2023-04-13 11:51:03 +08:00
if (Feedback == SetPoint)//有数据搬运机制把AO中的数值映射到AI中所以二者会实时相同
2023-04-13 11:51:03 +08:00
{
SetHeartBeatValue();//执行每秒自加一
_timHeartBeatOfRange.Stop();
2023-04-13 11:51:03 +08:00
}
_trigHeartBeatError.CLK = _timHeartBeatOfRange.IsTimeout();//超时后才会置true
2023-04-13 11:51:03 +08:00
if (_trigHeartBeatError.Q)
EV.PostAlarmLog(Module, $"Alarm:PLC heartbeat error , Time ovre 10s");
2023-04-13 11:51:03 +08:00
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
private void SetHeartBeatValue()
2023-04-13 11:51:03 +08:00
{
_counter++;
2023-04-13 11:51:03 +08:00
if (_counter > 1000)
_counter = 0;
2023-04-13 11:51:03 +08:00
SetPoint = _counter;
2023-04-13 11:51:03 +08:00
}
public void Terminate()
{
}
public void Monitor()
{
}
public void Reset()
{
_trigHeartBeatError.RST = true;
2023-04-13 11:51:03 +08:00
}
}
}