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; } } public string Condition { get; set; }//AND,OR,EXOR,BLANK public bool IsFloatType { get; set; } 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, string condition = "AND") : base(diItem.Name, value, tip, cultureTip) { _di = diItem; Condition = condition; } public DiLimit(DIAccessor diItem, bool value, string condition) : base(diItem.Name, value, "", null) { _di = diItem; Condition = condition; } 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, string condition = "AND") : base(doItem.Name, value, tip, cultureTip) { _do = doItem; Condition = condition; } public DoLimit(DOAccessor doItem, bool value, string condition) : base(doItem.Name, value, "", null) { _do = doItem; Condition = condition; } 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 { /// //LT(less than) 小于 //LE(less than or equal to) 小于等于 //EQ(equal to) 等于 //NE(not equal to) 不等于 //GE(greater than or equal to)大于等于 //GT(greater than) 大于 //B(bool) /// private AOAccessor _ao; private float _limitFloatValue; private string _operator; private string _module = ""; public AoLimit(AOAccessor aoItem, string value, string condition, bool isFloatType = true) : base(aoItem.Name, true, "", null) { _ao = aoItem; Condition = condition; IsFloatType = isFloatType; //if (value.StartsWith(">=")) //{ // _operator = ">="; //} //else if (value.StartsWith("<=")) //{ // _operator = "<="; //} //else if (value.StartsWith(">")) //{ // _operator = ">"; //} //else if (value.StartsWith("<")) //{ // _operator = "<"; //} //else //{ // _operator = "="; //} if (value.Contains("GT")) { _operator = "GT"; } else if (value.Contains("GE")) { _operator = "GE"; } else if (value.Contains("NE")) { _operator = "NE"; } else if (value.Contains("EQ")) { _operator = "EQ"; } else if (value.Contains("LE")) { _operator = "LE"; } else if (value.Contains("LT")) { _operator = "LT"; } 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 "GT": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) > _limitFloatValue; case "GE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) >= _limitFloatValue; case "NE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) != _limitFloatValue; case "EQ": return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) - _limitFloatValue) < 0.000001; case "LE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) <= _limitFloatValue; case "LT": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) < _limitFloatValue; default: return false; } } } } internal class AiLimit : InterlockLimit { /// //LT(less than) 小于 //LE(less than or equal to) 小于等于 //EQ(equal to) 等于 //NE(not equal to) 不等于 //GE(greater than or equal to)大于等于 //GT(greater than) 大于 //B(bool) /// private AIAccessor _ai; private float _limitFloatValue; private string _operator; private string _module = ""; public AiLimit(AIAccessor aiItem, string value, string condition, bool isFloatType = true) : base(aiItem.Name, true, "", null) { _ai = aiItem; Condition = condition; IsFloatType = isFloatType; //if (value.StartsWith(">=")) //{ // _operator = ">="; //} //else if (value.StartsWith("<=")) //{ // _operator = "<="; //} //else if (value.StartsWith(">")) //{ // _operator = ">"; //} //else if (value.StartsWith("<")) //{ // _operator = "<"; //} //else //{ // _operator = "="; //} if (value.Contains("GT")) { _operator = "GT"; } else if (value.Contains("GE")) { _operator = "GE"; } else if (value.Contains("NE")) { _operator = "NE"; } else if (value.Contains("EQ")) { _operator = "EQ"; } else if (value.Contains("LE")) { _operator = "LE"; } else if (value.Contains("LT")) { _operator = "LT"; } 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 "GT": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) > _limitFloatValue; case "GE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) >= _limitFloatValue; case "NE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) != _limitFloatValue; case "EQ": return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) - _limitFloatValue) < 0.000001; case "LE": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) <= _limitFloatValue; case "LT": return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) < _limitFloatValue; default: return false; } } } } internal class UserDefineLimit : InterlockLimit { public UserDefineLimit(string name, bool limitValue, string condition) : base(name, limitValue, "", null) { Condition = condition; } public override bool CurrentValue { get; } public override string LimitReason { get; } } internal class DataPollLimit : InterlockLimit { /// //LT(less than) 小于 //LE(less than or equal to) 小于等于 //EQ(equal to) 等于 //NE(not equal to) 不等于 //GE(greater than or equal to)大于等于 //GT(greater than) 大于 //B(bool) /// private string _operator; private string _operatorTip; private float _limitFloatValue; private bool _limitBoolValue; public DataPollLimit(string name, string limitValue, string condition) : base(name, true, "", null) { Condition = condition; if (limitValue.Contains("GT")) { _operator = "GT"; _operatorTip = ">"; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("GE")) { _operator = "GE"; _operatorTip = ">="; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("NE")) { _operator = "NE"; _operatorTip = "!="; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("EQ")) { _operator = "EQ"; _operatorTip = "=="; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("LE")) { _operator = "LE"; _operatorTip = "<="; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else if (limitValue.Contains("LT")) { _operator = "LT"; _operatorTip = "<"; float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue); } else { _operator = "B"; _operatorTip = "true"; _limitBoolValue = limitValue.ToUpper().Contains("ON") ? true : false; } } public override bool CurrentValue { get { switch (_operator) { case "GT": float.TryParse(DATA.Poll(Name).ToString(), out float valueGT); return valueGT > _limitFloatValue; case "GE": float.TryParse(DATA.Poll(Name).ToString(), out float valueGE); return valueGE >= _limitFloatValue; case "NE": float.TryParse(DATA.Poll(Name).ToString(), out float valueNE); return valueNE != _limitFloatValue; case "EQ": float.TryParse(DATA.Poll(Name).ToString(), out float valueEQ); return valueEQ == _limitFloatValue; case "LE": float.TryParse(DATA.Poll(Name).ToString(), out float valueLE); return valueLE <= _limitFloatValue; case "LT": float.TryParse(DATA.Poll(Name).ToString(), out float valueLT); return valueLT < _limitFloatValue; case "B": bool.TryParse(DATA.Poll(Name).ToString(), out bool valueB); return !(valueB ^ _limitBoolValue); default: return false; } } } public override string LimitReason { get { return $"DATA.Poll-{Name} = [{DATA.Poll(Name)}] not {_operatorTip} {(_operator == "B" ? _limitBoolValue.ToString() : _limitFloatValue.ToString())}"; } } } 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; } } }