2023-08-10 16:44:46 +08:00
|
|
|
|
using System.Collections.Generic;
|
2023-08-16 15:06:29 +08:00
|
|
|
|
using System.Linq;
|
2023-08-10 16:44:46 +08:00
|
|
|
|
using System.Text;
|
2023-08-16 15:06:29 +08:00
|
|
|
|
using Aitex.Core.RT.Event;
|
2023-08-18 10:06:41 +08:00
|
|
|
|
using Aitex.Core.RT.Log;
|
2023-08-16 15:06:29 +08:00
|
|
|
|
using Aitex.Core.Util;
|
|
|
|
|
using TypeDefLimitList = System.Collections.Generic.List<Aitex.Core.RT.IOCore.IInterlockLimit>;
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
2023-08-17 09:43:24 +08:00
|
|
|
|
namespace Aitex.Core.RT.IOCore.Interlock.Actions;
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
public class InterlockDaemonAction : InterlockActionBase
|
2023-08-10 16:44:46 +08:00
|
|
|
|
{
|
|
|
|
|
#region Variables
|
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
private readonly R_TRIG _rTrigSetDoFailed = new();
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
|
|
|
|
#endregion
|
2023-08-16 15:06:29 +08:00
|
|
|
|
|
2023-08-10 16:44:46 +08:00
|
|
|
|
#region Constructors
|
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
public InterlockDaemonAction(string module, DOAccessor doItem, bool value, string tip, Dictionary<string, string> cultureTip)
|
|
|
|
|
: base(module, doItem, value, tip, cultureTip)
|
|
|
|
|
{
|
2023-08-10 16:44:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2023-08-16 15:06:29 +08:00
|
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
|
|
2023-08-10 16:44:46 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 扫描当前动作的条件,并设置相关DO的输出状态。
|
|
|
|
|
/// </summary>
|
2023-08-16 15:06:29 +08:00
|
|
|
|
public override void Monitor()
|
2023-08-10 16:44:46 +08:00
|
|
|
|
{
|
|
|
|
|
var info = new StringBuilder();
|
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
// 检查所有的Limit是否满足要求
|
|
|
|
|
foreach (var limit in Limits)
|
2023-08-10 16:44:46 +08:00
|
|
|
|
{
|
|
|
|
|
if (!limit.CanDo(out _))
|
2023-08-16 15:06:29 +08:00
|
|
|
|
return;
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
2023-08-17 17:39:50 +08:00
|
|
|
|
info.AppendLine($"{limit.DaemonReason}");
|
2023-08-10 16:44:46 +08:00
|
|
|
|
}
|
2023-08-16 15:06:29 +08:00
|
|
|
|
|
|
|
|
|
// 扫描OR定义的Limit组,每个组中只要有一个Limit命中,则继续测试下个OR组;否则直接退出。
|
|
|
|
|
foreach (var group in LogicOrGroups)
|
|
|
|
|
{
|
|
|
|
|
var hitLimit = group.FirstOrDefault(limit => limit.CanDo(out _));
|
|
|
|
|
if (hitLimit == null) // 当前OR组中没用命中的Limit,退出Monitor
|
|
|
|
|
return;
|
|
|
|
|
|
2023-08-17 16:38:08 +08:00
|
|
|
|
info.AppendLine($"{hitLimit.DaemonReason}");
|
2023-08-16 15:06:29 +08:00
|
|
|
|
}
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
|
|
|
|
// 如果DO输出已经满足要求,则直接退出
|
2023-08-16 15:06:29 +08:00
|
|
|
|
if (_do.Value == _actionValue)
|
|
|
|
|
return;
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
// 所有的Limit和OR逻辑组均命中
|
|
|
|
|
var succeeded = _do.SetValue(_actionValue, out var reason);
|
|
|
|
|
_rTrigSetDoFailed.CLK = !succeeded;
|
|
|
|
|
if (succeeded)
|
|
|
|
|
{
|
|
|
|
|
info.Insert(0,
|
2023-08-18 10:06:41 +08:00
|
|
|
|
$"Interlock Daemon Force set DO-{_do.IoTableIndex}({_do.Name}) = [{((_actionValue) ? "ON" : "OFF")}] Due to\r\n");
|
2023-08-16 15:06:29 +08:00
|
|
|
|
|
2023-08-18 10:06:41 +08:00
|
|
|
|
EV.PostInfoLog( _module, info.ToString().TrimEnd('\r', '\n'));
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|
2023-08-16 15:06:29 +08:00
|
|
|
|
_rTrigSetDoFailed.CLK = false;
|
|
|
|
|
}
|
|
|
|
|
else if(_rTrigSetDoFailed.Q)
|
|
|
|
|
{
|
|
|
|
|
// 第一次Set DO错误时打印日志
|
2023-08-18 10:06:41 +08:00
|
|
|
|
LOG.Error($"Interlock Daemon set {_do.Name} failed, {reason}");
|
2023-08-16 15:06:29 +08:00
|
|
|
|
}
|
2023-08-10 16:44:46 +08:00
|
|
|
|
}
|
2023-08-16 15:06:29 +08:00
|
|
|
|
|
2023-08-10 16:44:46 +08:00
|
|
|
|
#endregion
|
2023-08-15 18:10:11 +08:00
|
|
|
|
}
|
2023-08-10 16:44:46 +08:00
|
|
|
|
|