parent
0a357a6369
commit
0ea1607d64
|
@ -678,7 +678,7 @@
|
|||
<Compile Include="MECF\Framework\Common\Device\Bases\ChillerBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\GasSplitterBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\HeaterBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\SignalTowerPartAction.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEventAction.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\SignalTowerBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\SignalTowerPartBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\LidBase.cs" />
|
||||
|
@ -694,6 +694,7 @@
|
|||
<Compile Include="MECF\Framework\Common\Device\Bases\STBlinkPattern.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEvent.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEvents.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\STPatternSetting.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\ThrottleValveBase.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\TowerLightStatus.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\VCEBase.cs" />
|
||||
|
|
|
@ -25,10 +25,15 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// <summary>
|
||||
/// 模式字符串中每个字符对应的延时时长,单位毫秒。
|
||||
/// </summary>
|
||||
private const uint DELAY_MS_PER_CHAR = 100;
|
||||
private const uint DELAY_MS_PER_CHAR = 100;
|
||||
|
||||
|
||||
private const string PATTERN_FAST = "-----..";
|
||||
private const string PATTERN_SLOW = "-----.......";
|
||||
private const string PATTERN_JOB_DONE = "-----.......";
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
|
@ -38,29 +43,32 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
public STBlinkPattern()
|
||||
{
|
||||
TotalCycles = 0;
|
||||
Pattern = "----------..........";
|
||||
Pattern = PATTERN_SLOW;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建信号灯塔元件闪烁模式对象的实例。
|
||||
/// </summary>
|
||||
/// <param name="cycle">总循环次数,0或负值表示无限循环。</param>
|
||||
/// <param name="pattern">
|
||||
/// /// <param name="pattern">
|
||||
/// 闪烁模式。
|
||||
/// 请参考属性<see cref="Pattern"/>以或许模式的设置方法。
|
||||
/// </param>
|
||||
public STBlinkPattern(string pattern, uint cycle = uint.MaxValue)
|
||||
/// <param name="priority">当前工作模式优先级。</param>
|
||||
/// <param name="cycle">总循环次数,0或负值表示无限循环。</param>
|
||||
public STBlinkPattern(string pattern, int priority, int cycle = int.MaxValue)
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(pattern), "pattern can not be null");
|
||||
|
||||
TotalCycles = cycle;
|
||||
Pattern = pattern;
|
||||
Priority = priority;
|
||||
IsPlcMode = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建信号灯塔元件闪烁模式对象的实例。
|
||||
/// </summary>
|
||||
/// <param name="priority">当前工作模式优先级。</param>
|
||||
/// <param name="cycle">总循环次数,0或负值表示无限循环。</param>
|
||||
/// <param name="frequencyHz">
|
||||
/// PLC控制模式下的闪烁频率。
|
||||
|
@ -68,11 +76,12 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// <param name="fallbackPattern">
|
||||
/// 如果PLC不支持设置闪烁频率,则回落到此模式。
|
||||
/// </param>
|
||||
public STBlinkPattern(float frequencyHz, uint cycle = uint.MaxValue, string fallbackPattern = "-----.....")
|
||||
public STBlinkPattern(float frequencyHz, int priority, int cycle = int.MaxValue, string fallbackPattern = PATTERN_SLOW)
|
||||
{
|
||||
TotalCycles = cycle;
|
||||
Pattern = fallbackPattern;
|
||||
FrequencyHz = frequencyHz;
|
||||
Priority = priority;
|
||||
IsPlcMode = true;
|
||||
}
|
||||
|
||||
|
@ -93,7 +102,7 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// 设置或返回总循环次数。
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public uint TotalCycles { get; set; }
|
||||
public int TotalCycles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置或返回闪烁模式。
|
||||
|
@ -111,6 +120,11 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// 闪烁频率。
|
||||
/// </summary>
|
||||
public float FrequencyHz { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前工作模式的优先级。
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -119,13 +133,14 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// <summary>
|
||||
/// 解析闪烁模式字串,生成闪烁数据供M<see cref="SignalTowerPartBase"/>产生闪烁效果。
|
||||
/// </summary>
|
||||
/// <param name="pattern"></param>
|
||||
/// <param name="blinkData">闪烁效果数据。</param>
|
||||
/// <param name="reason">解析失败原因。</param>
|
||||
/// <returns>
|
||||
/// <value>True: 解析成功</value>
|
||||
/// <value>False: 解析失败</value>
|
||||
/// </returns>
|
||||
public bool Parse(out List<BlinkDataType> blinkData, out string reason)
|
||||
public static bool GetBlinkData(STBlinkPattern pattern, out List<BlinkDataType> blinkData, out string reason)
|
||||
{
|
||||
// var regex = new Regex(@"(([-\.])(\2*))");
|
||||
|
||||
|
@ -138,7 +153,7 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
// Pattern分组正则
|
||||
var regGroup = new Regex(@"([\-\.])\1*");
|
||||
|
||||
if (!regPatternFormat.IsMatch(Pattern))
|
||||
if (!regPatternFormat.IsMatch(pattern.Pattern))
|
||||
{
|
||||
// 如果存在除-和.以外的字符,则为非法Pattern字串。
|
||||
reason = "pattern contains illegal characters";
|
||||
|
@ -146,7 +161,7 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
return false;
|
||||
}
|
||||
|
||||
var matches = regGroup.Matches(Pattern);
|
||||
var matches = regGroup.Matches(pattern.Pattern);
|
||||
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
|
@ -205,8 +220,11 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
if (obj is not STBlinkPattern target)
|
||||
return -1;
|
||||
|
||||
return (target.IsPlcMode == IsPlcMode && target.TotalCycles == TotalCycles &&
|
||||
Math.Abs(target.FrequencyHz - FrequencyHz) < 0.01 && target.Pattern == Pattern)
|
||||
return (target.IsPlcMode == IsPlcMode
|
||||
&& target.TotalCycles == TotalCycles
|
||||
&& Math.Abs(target.FrequencyHz - FrequencyHz) < 0.01
|
||||
&& target.Pattern == Pattern
|
||||
&& target.Priority == Priority)
|
||||
? 0
|
||||
: -1;
|
||||
}
|
||||
|
@ -218,22 +236,11 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// 开200ms,关200ms,无限循环。
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public static STBlinkPattern GetFastBlinkPattern()
|
||||
public static STBlinkPattern GetDefaultPattern()
|
||||
{
|
||||
return new STBlinkPattern("-----..");
|
||||
return new STBlinkPattern(PATTERN_SLOW, (int)TowerLightStatus.Customized);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取预设的慢速闪烁模式。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 开1s,关1s,无限循环。
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public static STBlinkPattern GetSlowBlinkPattern()
|
||||
{
|
||||
return new STBlinkPattern("-----.......");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取预设的工艺完成闪烁模式。
|
||||
|
@ -242,23 +249,10 @@ public class STBlinkPattern : IComparable, ICloneable
|
|||
/// 以开200ms、关200ms方式连续闪烁3次,然后关1s,循环5次。
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
public static STBlinkPattern GetProcessDoneBlinkPattern()
|
||||
public static STBlinkPattern GetJobDonePattern()
|
||||
{
|
||||
return new STBlinkPattern("--..........");
|
||||
return new STBlinkPattern(PATTERN_JOB_DONE, -1);
|
||||
}
|
||||
|
||||
public static STBlinkPattern ParseSTEvent(string pattern, uint cycle = int.MaxValue)
|
||||
{
|
||||
// 如果指定了闪烁模式字串,则以软件方式生成Blink
|
||||
if (Regex.IsMatch(pattern, REG_PATT_BLINK_PATTERN))
|
||||
return new STBlinkPattern(pattern, cycle);
|
||||
|
||||
// 如果指定了闪烁频率数值,则以PLC方式生成Blink
|
||||
if(float.TryParse(pattern, out var freq))
|
||||
return new STBlinkPattern(freq, cycle);
|
||||
|
||||
return GetFastBlinkPattern();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
|
@ -39,5 +39,10 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
|
||||
[XmlAttribute]
|
||||
public string Buzzer5 { get; set; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <summary>
|
||||
/// 预设的信号灯塔元件动作。
|
||||
/// </summary>
|
||||
public class SignalTowerPartAction : IComparable, ICloneable
|
||||
public class STEventAction : IComparable, ICloneable
|
||||
{
|
||||
/// <summary>
|
||||
/// 信号灯塔元件动作构造函数。
|
||||
|
@ -13,16 +13,13 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <param name="light">信号灯类型。</param>
|
||||
/// <param name="status">信号灯输出状态。</param>
|
||||
/// <param name="blinkPattern">闪烁模式。如果传入空值,则自动调用
|
||||
/// <see cref="STBlinkPattern.GetFastBlinkPattern()"/>以创建默认闪烁模式。</param>
|
||||
public SignalTowerPartAction(LightType light, TowerLightStatus status, STBlinkPattern blinkPattern = null)
|
||||
/// <see cref="STBlinkPattern.GetDefaultPattern"/>以创建默认闪烁模式。</param>
|
||||
public STEventAction(LightType light, TowerLightStatus status, STBlinkPattern blinkPattern = null)
|
||||
{
|
||||
Light = light;
|
||||
Status = status;
|
||||
|
||||
if(blinkPattern != null)
|
||||
BlinkPattern = blinkPattern;
|
||||
else
|
||||
BlinkPattern = STBlinkPattern.GetFastBlinkPattern();
|
||||
BlinkPattern = blinkPattern ?? STBlinkPattern.GetDefaultPattern();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -43,29 +40,32 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
|
||||
#region Methods
|
||||
|
||||
public bool DoAction(out string reason)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is not SignalTowerPartAction target)
|
||||
if (obj is not STEventAction target)
|
||||
return -1;
|
||||
|
||||
return (BlinkPattern.CompareTo(target.BlinkPattern) == 0 && Status == target.Status && Light == target.Light) ? 0 : -1;
|
||||
return (BlinkPattern.CompareTo(target.BlinkPattern) == 0
|
||||
&& Status == target.Status
|
||||
&& Light == target.Light)
|
||||
? 0
|
||||
: -1;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Clone()
|
||||
{
|
||||
return new SignalTowerPartAction(Light, Status, (STBlinkPattern)BlinkPattern.Clone());
|
||||
return new STEventAction(Light, Status, (STBlinkPattern)BlinkPattern.Clone());
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Light}, {Status}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,11 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MECF.Framework.Common.Device.Bases
|
||||
{
|
||||
public class STEvents
|
||||
{
|
||||
[XmlElement(ElementName = "STEvent")]
|
||||
public List<STEvent> Events;
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// 返回工作模式模板。
|
||||
/// </summary>
|
||||
[XmlArray("STPatterns")]
|
||||
[XmlArrayItem("STPattern")]
|
||||
public List<STPatternSetting> PatternsSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回预定义的事件。
|
||||
/// </summary>
|
||||
[XmlArray("STEvents")]
|
||||
public List<STEvent> Events { get; set; }
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// 解析配置文件中定义的事件。
|
||||
/// </summary>
|
||||
/// <param name="events">
|
||||
/// 返回事件字典。
|
||||
/// <remarks>
|
||||
/// 事件字典的Key为事件名称,名称为RT中注册的Bool型数据,通过DATA.Poll访问。
|
||||
/// <br/>
|
||||
/// 事件动作为<see cref="STEventAction"/>动作列表,表示当上述事件为True时,指定的信号塔组件执行的动作。
|
||||
/// </remarks>
|
||||
/// </param>
|
||||
public void ParseEvents(out Dictionary<string, List<STEventAction>> events)
|
||||
{
|
||||
events = new Dictionary<string, List<STEventAction>>();
|
||||
|
||||
foreach (var stEvent in Events)
|
||||
{
|
||||
// 如果相同的事件已经添加,则不再重复添加
|
||||
if (events.ContainsKey(stEvent.Name))
|
||||
continue;
|
||||
|
||||
// 字典中创建一个事件项目
|
||||
events[stEvent.Name] = new List<STEventAction>();
|
||||
|
||||
// 解析当前事件执行的动作
|
||||
foreach (LightType light in Enum.GetValues(typeof(LightType)))
|
||||
{
|
||||
var obj = stEvent.GetType().GetProperty(light.ToString())?.GetValue(stEvent);
|
||||
if (obj != null)
|
||||
{
|
||||
var status = TowerLightStatus.Unknown;
|
||||
STBlinkPattern blinkPattern = null;
|
||||
|
||||
var str = obj.ToString().ToLower();
|
||||
if (str.Contains(TowerLightStatus.On.ToString().ToLower()))
|
||||
{
|
||||
status = TowerLightStatus.On;
|
||||
}
|
||||
else if (str.Contains(TowerLightStatus.Off.ToString().ToLower()))
|
||||
{
|
||||
status = TowerLightStatus.Off;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用工作模式配置中的项目
|
||||
var pattern = PatternsSettings.FirstOrDefault(x =>
|
||||
string.Compare(x.Name, str, StringComparison.OrdinalIgnoreCase) == 0);
|
||||
blinkPattern = pattern != null
|
||||
? new STBlinkPattern(pattern.Pattern, pattern.Priority, pattern.Cycles)
|
||||
: STBlinkPattern.GetDefaultPattern();
|
||||
|
||||
status = TowerLightStatus.Customized;
|
||||
}
|
||||
|
||||
events[stEvent.Name].Add(new STEventAction(light, status, blinkPattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
using System.Xml.Serialization;
|
||||
|
||||
namespace MECF.Framework.Common.Device.Bases;
|
||||
|
||||
public class STPatternSetting
|
||||
{
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前工作模式名称。
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前工作模式配置模板。
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "pattern")]
|
||||
public string Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前工作模式的最大循环次数。
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "cycles")]
|
||||
public int Cycles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回当前工作模式的优先级。
|
||||
/// <remarks>
|
||||
/// 数字越小优先级越高。当信号塔动作合并时,优先级高的动作会覆盖优先级底的动作。
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
[XmlAttribute(AttributeName = "priority")]
|
||||
public int Priority { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}, {Pattern}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
|
@ -11,7 +11,6 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
namespace MECF.Framework.Common.Device.Bases
|
||||
|
@ -33,7 +32,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <summary>
|
||||
/// 信号塔事件字典,从配置文件中读取。
|
||||
/// </summary>
|
||||
private Dictionary<string, List<SignalTowerPartAction>> _signalTowerEvent;
|
||||
private Dictionary<string, List<STEventAction>> _signalTowerEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 信号塔中组件字典。
|
||||
|
@ -43,7 +42,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <summary>
|
||||
/// 信号塔组件动作字典。
|
||||
/// </summary>
|
||||
private Dictionary<LightType, SignalTowerPartAction> _dicMergedActions;
|
||||
private Dictionary<LightType, STEventAction> _dicMergedActions;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -139,6 +138,11 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
_dicStParts.Add(light, new SignalTowerPartBase(light, doSw, aoBlinkFreq));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定的配置文件中解析信号塔事件。
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
private bool ParseSignalTowerEvent(string fileName)
|
||||
{
|
||||
try
|
||||
|
@ -151,79 +155,12 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
}
|
||||
|
||||
var stEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(cFileName));
|
||||
_signalTowerEvent = new Dictionary<string, List<SignalTowerPartAction>>();
|
||||
stEvents.ParseEvents(out var events);
|
||||
if (events == null)
|
||||
LOG.Error("Unable to parse the signal tower events from config file.");
|
||||
|
||||
// Blinking配置字符串规则:
|
||||
// 1、Blinking
|
||||
// 2、Blinking,---..
|
||||
// 3、Blinking,0.5
|
||||
// 在线校验:https://regex101.com/r/CescBw/1
|
||||
var regxBlinkPatternString =
|
||||
new Regex(
|
||||
@"^(([bB]linking){1}(,{1})(?(2)([-\.]+)$))|(([bB]linking){1}(,{1})(?(6)(\d+\.?\d*)$))|([bB]linking){1}$");
|
||||
|
||||
foreach (var stEvent in stEvents.Events)
|
||||
{
|
||||
if (!_signalTowerEvent.ContainsKey(stEvent.Name))
|
||||
{
|
||||
_signalTowerEvent[stEvent.Name] = new List<SignalTowerPartAction>();
|
||||
|
||||
foreach (LightType type in Enum.GetValues(typeof(LightType)))
|
||||
{
|
||||
if (!_dicStParts.ContainsKey(type))
|
||||
continue;
|
||||
|
||||
var obj = stEvent.GetType().GetProperty(type.ToString())?.GetValue(stEvent);
|
||||
if (obj != null)
|
||||
{
|
||||
TowerLightStatus status = TowerLightStatus.Unknown;
|
||||
STBlinkPattern blinkPattern = null;
|
||||
|
||||
var str = obj.ToString().ToLower();
|
||||
if (str.Contains("on"))
|
||||
{
|
||||
status = TowerLightStatus.On;
|
||||
}
|
||||
else if (str.Contains("off"))
|
||||
{
|
||||
status = TowerLightStatus.Off;
|
||||
}
|
||||
else if (str.Contains("warning"))
|
||||
{
|
||||
status = TowerLightStatus.Warning;
|
||||
blinkPattern = STBlinkPattern.GetSlowBlinkPattern();
|
||||
}
|
||||
else if (str.Contains("alarm"))
|
||||
{
|
||||
status = TowerLightStatus.Alarm;
|
||||
blinkPattern = STBlinkPattern.GetFastBlinkPattern();
|
||||
}
|
||||
else if(str.StartsWith(TowerLightStatus.Blinking.ToString().ToLower()))
|
||||
{
|
||||
// 如果配置为闪烁方式,检查配置中是否包含BlinkPattern字串
|
||||
var matches = regxBlinkPatternString.Match(str);
|
||||
if (matches.Success)
|
||||
{
|
||||
if (matches.Groups[9].Success) // Blinking
|
||||
blinkPattern = STBlinkPattern.GetSlowBlinkPattern();
|
||||
else if (matches.Groups[6].Success) // Blinking,00.0
|
||||
blinkPattern = STBlinkPattern.ParseSTEvent(matches.Groups[8].Value);
|
||||
else if (matches.Groups[2].Success) // Blinking,--.-
|
||||
blinkPattern = STBlinkPattern.ParseSTEvent(matches.Groups[4].Value);
|
||||
else
|
||||
blinkPattern = STBlinkPattern.GetFastBlinkPattern();
|
||||
}
|
||||
|
||||
status = TowerLightStatus.Blinking;
|
||||
}
|
||||
|
||||
_signalTowerEvent[stEvent.Name].Add(new SignalTowerPartAction(type, status, blinkPattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
_signalTowerEvent = events;
|
||||
return _signalTowerEvent != null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -231,7 +168,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化信号塔对象实例。
|
||||
/// </summary>
|
||||
|
@ -299,7 +236,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
foreach (var action in _dicMergedActions)
|
||||
{
|
||||
// 创建一个动作副本,解决蜂鸣器被手动关闭后无法启用的问题
|
||||
var clonedAction = (SignalTowerPartAction)action.Value?.Clone();
|
||||
var clonedAction = (STEventAction)action.Value?.Clone();
|
||||
if(clonedAction == null)
|
||||
continue;
|
||||
|
||||
|
@ -334,7 +271,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
{
|
||||
// 强制使能蜂鸣器
|
||||
_switchBuzzerOff = false;
|
||||
lightInstance.SetAction(new SignalTowerPartAction(lightInstance.Light, TowerLightStatus.Blinking,
|
||||
lightInstance.SetAction(new STEventAction(lightInstance.Light, TowerLightStatus.Customized,
|
||||
pattern));
|
||||
return true;
|
||||
}
|
||||
|
@ -369,7 +306,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <summary>
|
||||
/// 合并信号事件。
|
||||
/// <remarks>
|
||||
/// 根据<see cref="SignalTowerPartAction.Status"/>的优先级决定执行的动作。
|
||||
/// 根据<see cref="STEventAction.Status"/>的优先级决定执行的动作。
|
||||
/// <br/>
|
||||
/// 此属性的数值越小,表示优先级越高。
|
||||
/// </remarks>
|
||||
|
@ -377,13 +314,25 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <param name="currentAction">当前输出状态。</param>
|
||||
/// <param name="nextAction">期望的输出状态。</param>
|
||||
/// <returns>合并后的信号灯输出状态。</returns>
|
||||
private SignalTowerPartAction MergeAction(SignalTowerPartAction currentAction, SignalTowerPartAction nextAction)
|
||||
private STEventAction MergeAction(STEventAction currentAction, STEventAction nextAction)
|
||||
{
|
||||
if (currentAction == null)
|
||||
return nextAction;
|
||||
if (nextAction == null)
|
||||
return currentAction;
|
||||
return (int)currentAction.Status < (int)nextAction.Status ? currentAction : nextAction;
|
||||
|
||||
// 获取当前动作的优先级
|
||||
var curPrior = currentAction.Status == TowerLightStatus.Customized
|
||||
? currentAction.BlinkPattern.Priority
|
||||
: (int)currentAction.Status;
|
||||
|
||||
// 获取下一个动作的优先级
|
||||
var nextPrior = nextAction.Status == TowerLightStatus.Customized
|
||||
? nextAction.BlinkPattern.Priority
|
||||
: (int)nextAction.Status;
|
||||
|
||||
|
||||
return curPrior < nextPrior ? currentAction : nextAction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -402,4 +351,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -36,13 +36,13 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
private DOAccessor _doLight;
|
||||
private AOAccessor _aoBlinkFreqHz;
|
||||
private readonly LightType _lightType;
|
||||
private SignalTowerPartAction _action;
|
||||
private STEventAction _action;
|
||||
|
||||
/// <summary>
|
||||
/// 闪烁次数计数器。
|
||||
/// <remarks>当该计数器归零时,结束闪烁。</remarks>
|
||||
/// </summary>
|
||||
private uint _blinkCycleDownCounter;
|
||||
private int _blinkCycleDownCounter;
|
||||
|
||||
private STBlinkPattern _blinkPattern;
|
||||
private List<BlinkDataType> _blinkData;
|
||||
|
@ -115,9 +115,8 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
Reset();
|
||||
}
|
||||
|
||||
if (_blinkCycleDownCounter > 0
|
||||
&& (_action.Status == TowerLightStatus.Blinking || _action.Status == TowerLightStatus.Alarm ||
|
||||
_action.Status == TowerLightStatus.Warning))
|
||||
// 如果动作状态指定使用自定义模式,并且循环次数未用完,则根据Pattern进行闪烁
|
||||
if (_action.Status == TowerLightStatus.Customized && _blinkCycleDownCounter > 0)
|
||||
{
|
||||
switch (_blinkStage)
|
||||
{
|
||||
|
@ -230,7 +229,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// 获取信号塔元件当前正在执行的动作。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SignalTowerPartAction GetAction()
|
||||
public STEventAction GetAction()
|
||||
{
|
||||
return _action;
|
||||
}
|
||||
|
@ -249,7 +248,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
/// <para>请参考<see cref="TowerLightStatus"/>枚举获取支持的动作类型。</para>
|
||||
/// </summary>
|
||||
/// <param name="action">信号灯的动作。</param>
|
||||
public void SetAction(SignalTowerPartAction action)
|
||||
public void SetAction(STEventAction action)
|
||||
{
|
||||
if (action == null)
|
||||
{
|
||||
|
@ -286,9 +285,7 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
Reset(); // 复位状态机
|
||||
break;
|
||||
|
||||
case TowerLightStatus.Alarm:
|
||||
case TowerLightStatus.Warning:
|
||||
case TowerLightStatus.Blinking:
|
||||
case TowerLightStatus.Customized:
|
||||
// 当工作在闪烁状态时,如果没有指定闪烁模式,则创建一个默认模式。
|
||||
_blinkPattern = _action.BlinkPattern;
|
||||
_blinkPattern ??= new STBlinkPattern();
|
||||
|
@ -297,23 +294,25 @@ namespace MECF.Framework.Common.Device.Bases
|
|||
if (_blinkPattern.IsPlcMode && _aoBlinkFreqHz != null)
|
||||
{
|
||||
_aoBlinkFreqHz.FloatValue = _blinkPattern.FrequencyHz;
|
||||
break;
|
||||
}
|
||||
|
||||
// 当循环次数小于等于0时,无限循环。
|
||||
_blinkCycleDownCounter = _blinkPattern.TotalCycles <= 0 ? int.MaxValue : _blinkPattern.TotalCycles;
|
||||
|
||||
// 解析闪烁模式数据。
|
||||
if (!_blinkPattern.Parse(out _blinkData, out var reason))
|
||||
else
|
||||
{
|
||||
// 如果闪烁模式解析错误,则常亮
|
||||
LOG.Error($"Unable to set {Light} to {action}, {reason}");
|
||||
_blinkData = new List<BlinkDataType>(new[] { new BlinkDataType(TowerLightStatus.On, 100) });
|
||||
}
|
||||
// 当循环次数小于等于0时,无限循环。
|
||||
_blinkCycleDownCounter = _blinkPattern.TotalCycles <= 0 ? int.MaxValue : _blinkPattern.TotalCycles;
|
||||
|
||||
// 使能状态机
|
||||
//! 注意:此步需放在最后,因为状态机异步使能,相关数据可能还未准备好
|
||||
_blinkStage = FsmStateBlink.Init;
|
||||
// 解析闪烁模式数据。
|
||||
if (!STBlinkPattern.GetBlinkData(_blinkPattern, out _blinkData, out var reason))
|
||||
{
|
||||
// 如果解析闪烁数据,如果解析错误,使用默认的闪烁模式。
|
||||
LOG.Error($"Unable to set {Light} to {action}, {reason}");
|
||||
STBlinkPattern.GetBlinkData(STBlinkPattern.GetDefaultPattern(), out _blinkData, out _);
|
||||
Debug.Assert(_blinkData != null);
|
||||
}
|
||||
|
||||
// 使能状态机
|
||||
//! 注意:此步需放在最后,因为状态机异步使能,相关数据可能还未准备好
|
||||
_blinkStage = FsmStateBlink.Init;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
|
|
@ -3,49 +3,33 @@ using System.Runtime.Serialization;
|
|||
|
||||
namespace MECF.Framework.Common.Device.Bases
|
||||
{
|
||||
/// <summary>
|
||||
/// 信号灯塔的控制状态枚举。
|
||||
/// <br/>
|
||||
/// 该枚举同时决定信号塔状态合并时的优先级,值越小优先级越高。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public enum TowerLightStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 预置的报警闪烁状态。
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Alarm,
|
||||
|
||||
/// <summary>
|
||||
/// 预置的警告闪烁状态。
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Warning,
|
||||
|
||||
/// <summary>
|
||||
/// 人工配置的闪烁状态
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Blinking,
|
||||
|
||||
/// <summary>
|
||||
/// 打开,灯亮或蜂鸣器响
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
On,
|
||||
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Off,
|
||||
|
||||
/// <summary>
|
||||
/// 未知状态
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Unknown
|
||||
}
|
||||
/// <summary>
|
||||
/// 信号灯塔的控制状态枚举。
|
||||
/// <br/>
|
||||
/// 该枚举同时决定信号塔状态合并时的优先级,值越小优先级越高。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public enum TowerLightStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用STEvents配置文件中配置的工作模式模板
|
||||
/// </summary>
|
||||
[EnumMember] Customized = int.MaxValue - 3,
|
||||
|
||||
/// <summary>
|
||||
/// 打开,灯亮或蜂鸣器响
|
||||
/// </summary>
|
||||
[EnumMember] On = int.MaxValue - 2,
|
||||
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
[EnumMember] Off = int.MaxValue - 1,
|
||||
|
||||
/// <summary>
|
||||
/// 未知状态
|
||||
/// </summary>
|
||||
[EnumMember] Unknown = int.MaxValue,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace MECF.Framework.Common.Device.Bases.Tests
|
|||
public void ParseTest1()
|
||||
{
|
||||
var pattern = new STBlinkPattern("-----.....", 5);
|
||||
var ret = pattern.Parse(out var blinkData, out var reason);
|
||||
var ret = STBlinkPattern.GetBlinkData(pattern, out var blinkData, out var reason);
|
||||
Assert.True(ret);
|
||||
Assert.True(blinkData.Count == 2);
|
||||
Assert.True(blinkData[0].Key == TowerLightStatus.On);
|
||||
|
@ -21,7 +21,7 @@ namespace MECF.Framework.Common.Device.Bases.Tests
|
|||
public void ParseTest2()
|
||||
{
|
||||
var pattern = new STBlinkPattern("..---...----", 5);
|
||||
var ret = pattern.Parse(out var blinkData, out var reason);
|
||||
var ret = STBlinkPattern.GetBlinkData(pattern, out var blinkData, out var reason);
|
||||
Assert.True(ret);
|
||||
Assert.True(blinkData.Count == 4);
|
||||
Assert.True(blinkData[0].Key == TowerLightStatus.Off);
|
||||
|
@ -38,7 +38,7 @@ namespace MECF.Framework.Common.Device.Bases.Tests
|
|||
public void ParseIllegalCharTest()
|
||||
{
|
||||
var pattern = new STBlinkPattern("..---...1----", 5);
|
||||
var ret = pattern.Parse(out var blinkData, out var reason);
|
||||
var ret = STBlinkPattern.GetBlinkData(pattern, out var blinkData, out var reason);
|
||||
Assert.False(ret);
|
||||
Assert.True(reason == "pattern contains illegal characters");
|
||||
|
||||
|
|
|
@ -784,7 +784,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
|
|||
{
|
||||
if (type == LightType.Buzzer)
|
||||
{
|
||||
type = state == TowerLightStatus.Blinking ? LightType.Buzzer2 : LightType.Buzzer1;
|
||||
type = state == TowerLightStatus.Customized ? LightType.Buzzer2 : LightType.Buzzer1;
|
||||
state = state == TowerLightStatus.Off ? TowerLightStatus.Off : TowerLightStatus.On;
|
||||
}
|
||||
|
||||
|
@ -803,7 +803,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
|
|||
{
|
||||
{TowerLightStatus.On, "ON"},
|
||||
{TowerLightStatus.Off, "OFF"},
|
||||
{TowerLightStatus.Blinking, "BLINK"},
|
||||
{TowerLightStatus.Customized, "BLINK"},
|
||||
};
|
||||
|
||||
string par1 = "STOWER";
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Aitex\Core\RT\IOCore\Interlock\InterlockManagerTests.cs" />
|
||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEventsTests.cs" />
|
||||
<Compile Include="MECF\Framework\Common\SicMath\TimeDomainArithmeticMeanFilterTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
@ -92,6 +93,9 @@
|
|||
<Content Include="SupportFiles\IoProviderConfig.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="SupportFiles\SignalTowerSettings.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="SupportFiles\_ioDefinePM1.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
using Aitex.Core.Util;
|
||||
using MECF.Framework.Common.Device.Bases;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
|
||||
namespace MECF.Framework.Common.Device.Bases.Tests
|
||||
{
|
||||
public class STEventsTests
|
||||
{
|
||||
private const string FN_STSETTINGS = "SupportFiles\\SignalTowerSettings.xml";
|
||||
|
||||
[Fact]
|
||||
public void LoadXmlFileTest()
|
||||
{
|
||||
var stEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(FN_STSETTINGS));
|
||||
Assert.NotNull(stEvents);
|
||||
Assert.True(stEvents.Events.Count > 0);
|
||||
Assert.True(stEvents.PatternsSettings.Count > 0);
|
||||
}
|
||||
|
||||
[Fact()]
|
||||
public void ParseEventsTest()
|
||||
{
|
||||
var stEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(FN_STSETTINGS));
|
||||
stEvents.ParseEvents(out var events);
|
||||
Assert.NotNull(events);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<STEvents>
|
||||
<STPatterns>
|
||||
<!--注意:"JobDone"为系统保留模式,请仅更改"pattern",其余属性请勿修改 -->
|
||||
<STPattern name="JobDone" pattern="--.........." cycles="-1" priority="-1" />
|
||||
<STPattern name="Alarm" pattern="-----.." cycles="-1" priority="0"/>
|
||||
<STPattern name="Warning" pattern="-----......." cycles="-1" priority="5"/>
|
||||
<STPattern name="Blink" pattern="----------.........." cycles="-1" priority="10"/>
|
||||
</STPatterns>
|
||||
|
||||
<STEvents>
|
||||
<STEvent name ="PM1.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="TM.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="LoadLock.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="UnLoad.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="Aligner.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="WaferRobot.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="TrayRobot.IsAlarm" Red="On" Yellow="Off" Green="Off" Buzzer="Alarm"/>
|
||||
<STEvent name ="PM1.IsWarning" Red="Off" Yellow="On" Green="Off" Buzzer="Warning"/>
|
||||
<STEvent name ="TM.IsWarning" Red="Off" Yellow="On" Green="Off" Buzzer="Warning"/>
|
||||
<STEvent name ="PM1.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="TM.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="LoadLock.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="UnLoad.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="Aligner.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="WaferRobot.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="TrayRobot.IsBusy" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
<STEvent name ="System.IsAutoRunning" Red="Off" Yellow="Off" Green="On" Buzzer="Off"/>
|
||||
</STEvents>
|
||||
</STEvents>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue