Limit类新增ignoreReverse属性,=true忽略单项limit反转Action
This commit is contained in:
parent
d841220f69
commit
8f66a4d067
|
@ -41,6 +41,11 @@ public interface IInterlockLimit
|
|||
/// </summary>
|
||||
string Tip { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回该Limit是否对Action进行反转
|
||||
/// </summary>
|
||||
bool IgnoreReverse { get; }
|
||||
|
||||
/*/// <summary>
|
||||
/// 判断两个互锁限制条件是否相等。
|
||||
/// </summary>
|
||||
|
@ -66,7 +71,6 @@ public interface IInterlockLimit
|
|||
/// <returns></returns>
|
||||
bool CanDo(out string reason);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定互锁限制条件中限制条件的内容。
|
||||
/// </summary>
|
||||
|
|
|
@ -163,11 +163,11 @@ public abstract class InterlockManagerBase<TAction>
|
|||
if (actionNode.HasAttribute("tip.en-US"))
|
||||
dicTips["en-US"] = actionNode.GetAttribute("tip.en-US");
|
||||
|
||||
var ignoreReverse = false;
|
||||
var ignoreReverse_All = false;//单个Action的全局ignore,为True时所有Limit条件不反向控制
|
||||
if (actionNode.HasAttribute("ignoreReverse"))
|
||||
{
|
||||
var strIgnoreReverse = actionNode.GetAttribute("ignoreReverse");
|
||||
if (!bool.TryParse(strIgnoreReverse, out ignoreReverse))
|
||||
if (!bool.TryParse(strIgnoreReverse, out ignoreReverse_All))
|
||||
LOG.Error($"Unable to convert attribute 'ignoreReverse' of action '{doName}' to bool.");
|
||||
}
|
||||
|
||||
|
@ -213,17 +213,21 @@ public abstract class InterlockManagerBase<TAction>
|
|||
_lstActions.Add(action);
|
||||
|
||||
// 如果当前Action设置了忽略翻转,则不要注册Limit到当前Action的映射,避免Limit触发导致Action翻转。
|
||||
if (!ignoreReverse)
|
||||
if (!ignoreReverse_All)
|
||||
{
|
||||
foreach (var limit in action.Limits)
|
||||
{
|
||||
// 创建以Limit分组的Action字典
|
||||
if (!_dicLimitToActionMap.ContainsKey(limit))
|
||||
_dicLimitToActionMap[limit] = new List<IInterlockAction>();
|
||||
if (!limit.IgnoreReverse)//如果单个limit也忽略反转,不要注册Limit到当前Action的映射,避免Limit触发导致Action翻转。
|
||||
{
|
||||
// 创建以Limit分组的Action字典
|
||||
if (!_dicLimitToActionMap.ContainsKey(limit))
|
||||
_dicLimitToActionMap[limit] = new List<IInterlockAction>();
|
||||
|
||||
_dicLimitToActionMap[limit].Add(action);
|
||||
_dicLimitToActionMap[limit].Add(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Debug.Assert(!_dicActionsPerModule.ContainsKey(ModuleName.UnDefined),
|
||||
|
@ -302,6 +306,14 @@ public abstract class InterlockManagerBase<TAction>
|
|||
tip = dicLimitTips["en-US"];
|
||||
}
|
||||
|
||||
var ignoreReverse = false;
|
||||
if (limitNode.HasAttribute("ignoreReverse"))
|
||||
{
|
||||
var strIgnoreReverse = limitNode.GetAttribute("ignoreReverse");
|
||||
if (!bool.TryParse(strIgnoreReverse, out ignoreReverse))
|
||||
LOG.Error($"Unable to convert attribute 'ignoreReverse' of Limit to bool.");
|
||||
}
|
||||
|
||||
// 节点不包含‘di’、‘do’、‘ai’、‘ao’,或者不包含‘value’属性
|
||||
IInterlockLimit limit;
|
||||
if (limitNode.HasAttribute("di"))
|
||||
|
@ -309,40 +321,40 @@ public abstract class InterlockManagerBase<TAction>
|
|||
var limitName = limitNode.GetAttribute("di");
|
||||
var io = GetIoByIoType(IOType.DI, limitName);
|
||||
var provider = new DiValueProvider((DIAccessor)io);
|
||||
limit = new DiLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new DiLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else if (limitNode.HasAttribute("do"))
|
||||
{
|
||||
var limitName = limitNode.GetAttribute("do");
|
||||
var io = GetIoByIoType(IOType.DO, limitName);
|
||||
var provider = new DoValueProvider((DOAccessor)io);
|
||||
limit = new DoLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new DoLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else if (limitNode.HasAttribute("ai"))
|
||||
{
|
||||
var limitName = limitNode.GetAttribute("ai");
|
||||
var io = GetIoByIoType(IOType.AI, limitName);
|
||||
var provider = new AiValueProvider((AIAccessor)io);
|
||||
limit = new AiLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new AiLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else if (limitNode.HasAttribute("ao"))
|
||||
{
|
||||
var limitName = limitNode.GetAttribute("ao");
|
||||
var io = GetIoByIoType(IOType.AO, limitName);
|
||||
var provider = new AoValueProvider((AOAccessor)io);
|
||||
limit = new AoLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new AoLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else if (limitNode.HasAttribute("polldouble"))
|
||||
{
|
||||
var limitName = limitNode.GetAttribute("polldouble");
|
||||
var provider = new DoubleDataPollProvider(limitName);
|
||||
limit = new DoubleDataPollLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new DoubleDataPollLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else if (limitNode.HasAttribute("pollbool"))
|
||||
{
|
||||
var limitName = limitNode.GetAttribute("pollbool");
|
||||
var provider = new BoolDataPollProvider(limitName);
|
||||
limit = new BoolDataPollLimit(provider, limitValue, tip, dicLimitTips);
|
||||
limit = new BoolDataPollLimit(provider, limitValue, tip, dicLimitTips, ignoreReverse);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -12,8 +12,8 @@ internal class AiLimit : InterlockLimitBase<AiValueProvider, double>
|
|||
#region Constructors
|
||||
|
||||
public AiLimit(AiValueProvider dataProvider, string value, string tip,
|
||||
Dictionary<string, string> cultureTip)
|
||||
: base(dataProvider, value, tip, cultureTip)
|
||||
Dictionary<string, string> cultureTip,bool ignoreReverse)
|
||||
: base(dataProvider, value, tip, cultureTip, ignoreReverse)
|
||||
{
|
||||
LimitRange = new InterlockLimitRangeDouble(value);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ internal class AoLimit : InterlockLimitBase<AoValueProvider, double>
|
|||
{
|
||||
#region Constructors
|
||||
|
||||
public AoLimit(AoValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip)
|
||||
: base(dataProvider, value, tip, cultureTip)
|
||||
public AoLimit(AoValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip, bool ignoreReverse)
|
||||
: base(dataProvider, value, tip, cultureTip, ignoreReverse)
|
||||
{
|
||||
LimitRange = new InterlockLimitRangeDouble(value);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ public class BoolDataPollLimit : InterlockLimitBase<BoolDataPollProvider, bool>
|
|||
#region Constructors
|
||||
|
||||
public BoolDataPollLimit(IInterlockLimitDataProvider dataProvider, string value, string tip,
|
||||
Dictionary<string, string> cultureTip) : base(dataProvider, value, tip, cultureTip)
|
||||
Dictionary<string, string> cultureTip,bool ignoreReverse) : base(dataProvider, value, tip, cultureTip, ignoreReverse)
|
||||
{
|
||||
if (bool.TryParse(value, out var limitValue))
|
||||
LimitValue = limitValue;
|
||||
|
|
|
@ -17,8 +17,8 @@ internal class DiLimit : InterlockLimitBase<DiValueProvider, bool>
|
|||
public override string DaemonReason =>
|
||||
$"{DataProvider.Name} = [{(LimitValue ? "ON" : "OFF")}]{(string.IsNullOrEmpty(Tip) ? "" : $",{Tip}")}";
|
||||
|
||||
public DiLimit(DiValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip)
|
||||
: base(dataProvider, value, tip, cultureTip)
|
||||
public DiLimit(DiValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip,bool ignoreReverse)
|
||||
: base(dataProvider, value, tip, cultureTip,ignoreReverse)
|
||||
{
|
||||
if (bool.TryParse(value, out var limitValue))
|
||||
LimitValue = limitValue;
|
||||
|
|
|
@ -17,8 +17,8 @@ internal class DoLimit : InterlockLimitBase<DoValueProvider, bool>
|
|||
public override string DaemonReason =>
|
||||
$"{DataProvider.Name} = [{(LimitValue ? "ON" : "OFF")}]{(string.IsNullOrEmpty(Tip) ? "" : $",{Tip}")}";
|
||||
|
||||
public DoLimit(DoValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip)
|
||||
: base(dataProvider, value, tip, cultureTip)
|
||||
public DoLimit(DoValueProvider dataProvider, string value, string tip, Dictionary<string, string> cultureTip, bool ignoreReverse)
|
||||
: base(dataProvider, value, tip, cultureTip, ignoreReverse)
|
||||
{
|
||||
if (bool.TryParse(value, out var limitValue))
|
||||
LimitValue = limitValue;
|
||||
|
|
|
@ -9,7 +9,7 @@ public class DoubleDataPollLimit : InterlockLimitBase<DoubleDataPollProvider, do
|
|||
#region Constructors
|
||||
|
||||
public DoubleDataPollLimit(IInterlockLimitDataProvider dataProvider, string value, string tip,
|
||||
Dictionary<string, string> cultureTip) : base(dataProvider, value, tip, cultureTip)
|
||||
Dictionary<string, string> cultureTip,bool ignoreReverse) : base(dataProvider, value, tip, cultureTip, ignoreReverse)
|
||||
{
|
||||
LimitRange = new InterlockLimitRangeDouble(value);
|
||||
}
|
||||
|
|
|
@ -16,20 +16,21 @@ public abstract class InterlockLimitBase<TAccessor, TValue> : IInterlockLimit
|
|||
private Dictionary<string, string> _cultureTip;
|
||||
private readonly R_TRIG _trigger;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// 互锁限制条件的构造函数。
|
||||
/// </summary>
|
||||
/// <param name="dataProvider">数据供应器对象实例</param>
|
||||
/// <param name="value">当前限制条件中的IO状态。</param>
|
||||
/// <param name="tip">默认语言提示信息。</param>
|
||||
/// <param name="cultureTip">多国语言提示信息。</param>
|
||||
/// <exception cref="InvalidIoNameException">IO名称错误,前缀不是“DI_”、”DO_“、”AI_“或"AO_".</exception>
|
||||
protected InterlockLimitBase(IInterlockLimitDataProvider dataProvider, string value, string tip,
|
||||
Dictionary<string, string> cultureTip)
|
||||
/// <summary>
|
||||
/// 互锁限制条件的构造函数。
|
||||
/// </summary>
|
||||
/// <param name="dataProvider">数据供应器对象实例</param>
|
||||
/// <param name="value">当前限制条件中的IO状态。</param>
|
||||
/// <param name="tip">默认语言提示信息。</param>
|
||||
/// <param name="cultureTip">多国语言提示信息。</param>
|
||||
/// <param name="ignoreReverse">是否触发Action反转</param>
|
||||
/// <exception cref="InvalidIoNameException">IO名称错误,前缀不是“DI_”、”DO_“、”AI_“或"AO_".</exception>
|
||||
protected InterlockLimitBase(IInterlockLimitDataProvider dataProvider, string value, string tip,
|
||||
Dictionary<string, string> cultureTip,bool ignoreReverse = false)
|
||||
{
|
||||
Debug.Assert(dataProvider != null, "The data provider can not be null.");
|
||||
_trigger = new R_TRIG();
|
||||
|
@ -37,6 +38,7 @@ public abstract class InterlockLimitBase<TAccessor, TValue> : IInterlockLimit
|
|||
Tip = tip;
|
||||
_cultureTip = cultureTip;
|
||||
UniqueId = $"{dataProvider.Name}.{value}";
|
||||
IgnoreReverse = ignoreReverse;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -93,11 +95,16 @@ public abstract class InterlockLimitBase<TAccessor, TValue> : IInterlockLimit
|
|||
/// </summary>
|
||||
public string Tip { get; }
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 返回该Limit是否对Action进行反转
|
||||
/// </summary>
|
||||
public bool IgnoreReverse { get; }
|
||||
|
||||
#region Methods
|
||||
#endregion
|
||||
|
||||
/*
|
||||
#region Methods
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// 判断两个互锁限制条件是否相等。
|
||||
/// </summary>
|
||||
|
@ -112,14 +119,14 @@ public abstract class InterlockLimitBase<TAccessor, TValue> : IInterlockLimit
|
|||
return Name == li.Name && li.LimitValue == LimitValue;
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// 返回互锁限制监测的信号当前值和期望值不相等的条件是否触发。
|
||||
/// <remarks>
|
||||
/// 捕获当前值和期望值不相等信号的上升沿,当上升沿到达时触发输出Q。
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsTriggered()
|
||||
/// <summary>
|
||||
/// 返回互锁限制监测的信号当前值和期望值不相等的条件是否触发。
|
||||
/// <remarks>
|
||||
/// 捕获当前值和期望值不相等信号的上升沿,当上升沿到达时触发输出Q。
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsTriggered()
|
||||
{
|
||||
_trigger.CLK = !CheckInRange();
|
||||
return _trigger.Q;
|
||||
|
|
Loading…
Reference in New Issue