using System; using System.Collections.Generic; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using DocumentFormat.OpenXml.Spreadsheet; namespace Aitex.Core.RT.IOCore { /* * * */ public abstract class InterlockLimit { public string Name { get { return _name; } } public abstract bool CurrentValue { get; } public abstract string LimitReason { get; } public bool LimitValue { get { return _limitValue; } } public string Tip { get { return _tip; } } private string _name; private bool _limitValue; private string _tip; private Dictionary _cultureTip = new Dictionary(); R_TRIG _trigger = new R_TRIG(); public InterlockLimit(string name, bool value, string tip, Dictionary cultureTip) { _name = name; _limitValue = value; _tip = tip; _cultureTip = cultureTip; } public bool IsSame(string name, bool value) { return (name == _name) && (_limitValue == value); } public bool IsSame(InterlockLimit limit) { return (limit.Name == _name) && (_limitValue == limit.LimitValue); } public bool IsTriggered() { _trigger.CLK = CurrentValue != _limitValue; return _trigger.Q; } public bool CanDo(out string reason) { reason = string.Empty; if (CurrentValue == _limitValue) return true; reason = LimitReason; return false; } } internal class DiLimit:InterlockLimit { private DIAccessor _di; public DiLimit(DIAccessor diItem, bool value, string tip, Dictionary cultureTip) :base(diItem.Name, value, tip, cultureTip) { _di = diItem; } public override bool CurrentValue { get { return _di.Value; } } public override string LimitReason { get { return string.Format("DI-{0}({1}) = [{2}],{3}", _di.IoTableIndex, _di.Name, _di.Value ? "ON" : "OFF", Tip); } } } internal class DoLimit : InterlockLimit { private DOAccessor _do; public DoLimit(DOAccessor doItem, bool value, string tip, Dictionary cultureTip) : base(doItem.Name, value, tip, cultureTip) { _do = doItem; } public override bool CurrentValue { get { return _do.Value; } } public override string LimitReason { get { return string.Format("DO-{0}({1}) = [{2}],{3}", _do.IoTableIndex, _do.Name, _do.Value ? "ON" : "OFF", Tip); } } } internal class AoLimit : InterlockLimit { private AOAccessor _ao; private float _limitFloatValue; //private string _operator;//>,>=,<,<=,= private string _operator;//H:>=,L:< private string _module = ""; public AoLimit(AOAccessor aoItem, string value) : base(aoItem.Name, true, "", null) { _ao = aoItem; if (value.Contains("H")) { _operator = "H"; } else if (value.Contains("L")) { _operator = "L"; } float.TryParse(value.Replace(_operator, ""), out _limitFloatValue); var paras = aoItem.Name.Split('.'); if (paras != null && paras.Length > 1) _module = paras[0]; } public override string LimitReason { get { return string.Format("AO-{0}({1}) = [{2}],{3}", _ao.IoTableIndex, _ao.Name, (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value), Tip); } } public override bool CurrentValue { get { switch (_operator) { case "H"://>= return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) >= _limitFloatValue; case "L"://< return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) < _limitFloatValue; default://= return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) - _limitFloatValue) < 0.000001; } } } } internal class AiLimit : InterlockLimit { private AIAccessor _ai; private float _limitFloatValue; //private string _operator;//>,>=,<,<=,= private string _operator;//H:>=,L:< private string _module = ""; public AiLimit(AIAccessor aiItem, string value) : base(aiItem.Name, true, "", null) { _ai = aiItem; if (value.Contains("H")) { _operator = "H"; } else if (value.Contains("L")) { _operator = "L"; } float.TryParse(value.Replace(_operator, ""), out _limitFloatValue); var paras = aiItem.Name.Split('.'); if (paras != null && paras.Length > 1) _module = paras[0]; } public override string LimitReason { get { return string.Format("AO-{0}({1}) = [{2}],{3}", _ai.IoTableIndex, _ai.Name, (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value), Tip); } } public override bool CurrentValue { get { //switch (_operator) //{ // case ">=": // return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) >= _limitFloatValue; // case "<=": // return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) <= _limitFloatValue; // case ">": // return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) > _limitFloatValue; // case "<": // return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) < _limitFloatValue; // default://= // return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) - _limitFloatValue) < 0.000001; //} switch (_operator) { case "H"://>= return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) >= _limitFloatValue; case "L"://< return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) < _limitFloatValue; default://= return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) - _limitFloatValue) < 0.000001; } } } } internal class DataPollLimit : InterlockLimit { private string _operator;//H:>=,L:<,B private float _limitFloatValue; private bool _limitBoolValue; public DataPollLimit(string name, string limitValue) : base(name, true, "", null) { if (limitValue.Contains("H")) { _operator = "H"; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("L")) { _operator = "L"; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("B")) { _operator = "B"; bool.TryParse(limitValue.Replace(_operator, ""), out _limitBoolValue); } } public override bool CurrentValue { get { switch (_operator) { case "H"://>= float.TryParse(DATA.Poll(Name).ToString(), out float valueH); return valueH >= _limitFloatValue; case "L"://< float.TryParse(DATA.Poll(Name).ToString(), out float valueL); return valueL < _limitFloatValue; case "B"://< bool.TryParse(DATA.Poll(Name).ToString(), out bool valueB); return valueB && _limitBoolValue; default://= return false; } } } public override string LimitReason { get; } } public class CustomLimitBase : InterlockLimit { public CustomLimitBase(string name, bool limitValue, string tip, Dictionary cultureTip) : base(name, limitValue, tip, cultureTip) { } public override bool CurrentValue { get; } public override string LimitReason { get; } } }