using System.Collections.Generic; using System.Text; namespace Aitex.Core.RT.IOCore { internal class InterlockAction { private readonly List _limits; private readonly DOAccessor _do; private readonly bool _actionValue; private readonly string _tip; private Dictionary _cultureTip; public string ActionName => (_do != null) ? _do.Name : ""; public InterlockAction(DOAccessor doItem, bool value, string tip, Dictionary cultureTip, List limits) { _do = doItem; _actionValue = value; _tip = tip; _cultureTip = cultureTip; _limits = limits; } public bool IsSame(string doName, bool value) { return doName == _do.Name && _actionValue == value; } /// /// 如果命中某个互锁限制条件,则将DO电平恢复到Action定义的反向电平。 /// /// 执行恢复电平动作的信息。 /// /// True:执行了电平恢复操作;False:未操作电平 /// public bool TryReverse(out string reason) { reason = string.Empty; // 如果DO当前电平不等于Action定义的电平,则啥也不干 if (_do.Value != _actionValue) return false; // 如果DO已经输出Action定义的电平,则反向 if (_do.SetValue(!_actionValue, out reason)) reason = $"Interlock Force set DO-{_do.IoTableIndex}({_do.Name}) = [{((!_actionValue) ? "ON" : "OFF")}]"; return true; } public bool CanDo(out string reason) { reason = string.Empty; var sbReason = new StringBuilder(); var result = true; foreach (var limit in _limits) { if (!limit.CanDo(out var limitReason)) { sbReason.AppendLine(limitReason); result = false; } } // 如果有互锁被触发,则打印互锁信息 if (!result) { sbReason.Insert(0, $"Interlock triggered, DO-{_do.IoTableIndex}({_do.Name}) can not be [{(_actionValue ? "ON" : "OFF")}]{(string.IsNullOrEmpty(_tip) ? "" : $",{_tip}")} \r\n"); reason = sbReason.ToString().TrimEnd('\r', '\n'); } return result; } public override string ToString() { return $"{ActionName}, Action={_actionValue}, Limit Count={_limits.Count}"; } } }