parent
163d2ecad0
commit
0cfe77d1aa
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using Aitex.Core.Account;
|
using Aitex.Core.Account;
|
||||||
using Aitex.Core.RT.DataCenter;
|
using Aitex.Core.RT.DataCenter;
|
||||||
|
@ -227,7 +228,9 @@ namespace Aitex.Core.RT.Event
|
||||||
|
|
||||||
OP.Subscribe("System.Diagnosis.GenPjDoneEvent", (s, args) =>
|
OP.Subscribe("System.Diagnosis.GenPjDoneEvent", (s, args) =>
|
||||||
{
|
{
|
||||||
WriteEvent(ModuleName.System.ToString(), "PJ_DONE", "LoadLock", "0");
|
//WriteEvent(ModuleName.System.ToString(), "PJ_DONE", "LoadLock", "0");
|
||||||
|
EV.PostMessage(ModuleName.System.ToString(), EventEnum.PJ_DONE, "LoadLock", "0");
|
||||||
|
OP.DoOperation("System.AlertJobDone");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -704,9 +704,9 @@
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\ChillerBase.cs" />
|
<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\GasSplitterBase.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\HeaterBase.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\HeaterBase.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEventAction.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\STAction.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\SignalTowerBase.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\SignalTowerLightBase.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\LidBase.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\LidBase.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\LightType.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\LightType.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\MfcBase.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\MfcBase.cs" />
|
||||||
|
@ -722,7 +722,7 @@
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\STEvents.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\STPatternSetting.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\ThrottleValveBase.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\SignalTowerActions.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Device\Bases\VCEBase.cs" />
|
<Compile Include="MECF\Framework\Common\Device\Bases\VCEBase.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Equipment\ModuleHelper.cs" />
|
<Compile Include="MECF\Framework\Common\Equipment\ModuleHelper.cs" />
|
||||||
<Compile Include="MECF\Framework\Common\Equipment\ModuleName.cs" />
|
<Compile Include="MECF\Framework\Common\Equipment\ModuleName.cs" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace MECF.Framework.Common.Device.Bases
|
namespace MECF.Framework.Common.Device.Bases
|
||||||
{
|
{
|
||||||
public enum LightType
|
public enum STLightTypes
|
||||||
{
|
{
|
||||||
Red = 0,
|
Red = 0,
|
||||||
Yellow = 1,
|
Yellow = 1,
|
||||||
|
|
|
@ -5,24 +5,25 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 预设的信号灯塔元件动作。
|
/// 预设的信号灯塔元件动作。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class STEventAction : IComparable, ICloneable
|
public class STAction : IComparable, ICloneable
|
||||||
{
|
{
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信号灯塔元件动作构造函数。
|
/// 信号灯塔元件动作构造函数。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">动作名称。</param>
|
/// <param name="eventName">动作名称。</param>
|
||||||
/// <param name="light">信号塔组件对象的实例。</param>
|
/// <param name="light">信号塔组件对象的实例。</param>
|
||||||
/// <param name="status">信号塔组件输出状态。</param>
|
/// <param name="action">信号塔组件输出状态。</param>
|
||||||
/// <param name="blinkPattern">信号塔组件工作模式。如果传入空值,则自动调用
|
/// <param name="blinkPattern">信号塔组件工作模式。如果传入空值,则自动调用
|
||||||
/// <see cref="STBlinkPattern.GetDefaultPattern"/>以创建默认工作模式。</param>
|
/// <see cref="STBlinkPattern.GetDefaultPattern"/>以创建默认工作模式。</param>
|
||||||
public STEventAction(string name, SignalTowerPartBase light, TowerLightStatus status, STBlinkPattern blinkPattern = null)
|
public STAction(string eventName, SignalTowerLightBase light, SignalTowerActions action, STBlinkPattern blinkPattern = null)
|
||||||
{
|
{
|
||||||
Name = name;
|
EventName = eventName;
|
||||||
StPart = light;
|
Light = light;
|
||||||
Status = status;
|
Output = action;
|
||||||
BlinkPattern = blinkPattern ?? STBlinkPattern.GetDefaultPattern();
|
BlinkPattern = blinkPattern ?? STBlinkPattern.GetDefaultPattern();
|
||||||
|
IsCycleDone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,26 +32,36 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 动作名称。
|
/// 动作对应的事件名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; }
|
public string EventName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返回执行当前动作的信号灯。
|
||||||
|
/// </summary>
|
||||||
|
public STLightTypes LightType => Light.Type;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回信号灯实例。
|
/// 返回信号灯实例。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SignalTowerPartBase StPart { get; }
|
public SignalTowerLightBase Light { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置或返回信号灯的输出状态。
|
/// 设置或返回信号灯的输出状态。
|
||||||
/// 支持的状态请参考<see cref="TowerLightStatus"/>枚举。
|
/// 支持的状态请参考<see cref="SignalTowerActions"/>枚举。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TowerLightStatus Status { get; set; }
|
public SignalTowerActions Output { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置或返回信号灯闪烁模式。
|
/// 设置或返回信号灯闪烁模式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public STBlinkPattern BlinkPattern { get; set; }
|
public STBlinkPattern BlinkPattern { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置或返回是否循环结束。
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCycleDone { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
@ -58,12 +69,12 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int CompareTo(object obj)
|
public int CompareTo(object obj)
|
||||||
{
|
{
|
||||||
if (obj is not STEventAction target)
|
if (obj is not STAction target)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return (BlinkPattern.CompareTo(target.BlinkPattern) == 0
|
return (BlinkPattern.CompareTo(target.BlinkPattern) == 0
|
||||||
&& Status == target.Status
|
&& Output == target.Output
|
||||||
&& StPart == target.StPart)
|
&& Light == target.Light)
|
||||||
? 0
|
? 0
|
||||||
: -1;
|
: -1;
|
||||||
}
|
}
|
||||||
|
@ -71,13 +82,13 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object Clone()
|
public object Clone()
|
||||||
{
|
{
|
||||||
return new STEventAction(Name, StPart, Status, (STBlinkPattern)BlinkPattern.Clone());
|
return new STAction(EventName, Light, Output, (STBlinkPattern)BlinkPattern.Clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{StPart}, {Status}";
|
return $"{Light}, {Output}";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
|
@ -4,7 +4,7 @@ using System.Diagnostics;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Aitex.Core.RT.Log;
|
using Aitex.Core.RT.Log;
|
||||||
using BlinkDataType = System.Collections.Generic.KeyValuePair<MECF.Framework.Common.Device.Bases.TowerLightStatus, uint>;
|
using BlinkDataType = System.Collections.Generic.KeyValuePair<MECF.Framework.Common.Device.Bases.SignalTowerActions, uint>;
|
||||||
|
|
||||||
namespace MECF.Framework.Common.Device.Bases;
|
namespace MECF.Framework.Common.Device.Bases;
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ public class STBlinkPattern : IComparable, ICloneable
|
||||||
#region Static Methods
|
#region Static Methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 解析闪烁模式字串,生成闪烁数据供M<see cref="SignalTowerPartBase"/>产生闪烁效果。
|
/// 解析闪烁模式字串,生成闪烁数据供M<see cref="SignalTowerLightBase"/>产生闪烁效果。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pattern"></param>
|
/// <param name="pattern"></param>
|
||||||
/// <param name="blinkData">闪烁效果数据。</param>
|
/// <param name="blinkData">闪烁效果数据。</param>
|
||||||
|
@ -171,14 +171,14 @@ public class STBlinkPattern : IComparable, ICloneable
|
||||||
var length = (uint)match.Length;
|
var length = (uint)match.Length;
|
||||||
|
|
||||||
// 根据每组的字符判断动作。
|
// 根据每组的字符判断动作。
|
||||||
TowerLightStatus action;
|
SignalTowerActions action;
|
||||||
switch (leadChar)
|
switch (leadChar)
|
||||||
{
|
{
|
||||||
case "-":
|
case "-":
|
||||||
action = TowerLightStatus.On;
|
action = SignalTowerActions.On;
|
||||||
break;
|
break;
|
||||||
case ".":
|
case ".":
|
||||||
action = TowerLightStatus.Off;
|
action = SignalTowerActions.Off;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -238,7 +238,7 @@ public class STBlinkPattern : IComparable, ICloneable
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static STBlinkPattern GetDefaultPattern()
|
public static STBlinkPattern GetDefaultPattern()
|
||||||
{
|
{
|
||||||
return new STBlinkPattern(PATTERN_SLOW, (int)TowerLightStatus.Customized);
|
return new STBlinkPattern(PATTERN_SLOW, (int)SignalTowerActions.Customized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,12 +246,12 @@ public class STBlinkPattern : IComparable, ICloneable
|
||||||
/// 获取预设的工艺完成闪烁模式。
|
/// 获取预设的工艺完成闪烁模式。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 以开200ms、关200ms方式连续闪烁3次,然后关1s,循环5次。
|
/// 以开200ms、关200ms方式连续闪烁3次,然后关1s,循环3次。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static STBlinkPattern GetJobDonePattern()
|
public static STBlinkPattern GetJobDonePattern()
|
||||||
{
|
{
|
||||||
return new STBlinkPattern(PATTERN_JOB_DONE, priority:-1);
|
return new STBlinkPattern(PATTERN_JOB_DONE, priority:-1, cycle:3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -32,9 +32,9 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// 解析配置文件中定义的事件。
|
/// 解析配置文件中定义的事件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dicLights">
|
/// <param name="dicLights">
|
||||||
/// 包含<see cref="SignalTowerPartBase"/>对象的字典。
|
/// 包含<see cref="SignalTowerLightBase"/>对象的字典。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <see cref="STEventAction"/>需要映射到相应的<see cref="SignalTowerPartBase"/>对象,因此需要传入相应的字典;
|
/// <see cref="STAction"/>需要映射到相应的<see cref="SignalTowerLightBase"/>对象,因此需要传入相应的字典;
|
||||||
/// 该字典在<see cref="SignalTowerBase"/>构造函数中创建。
|
/// 该字典在<see cref="SignalTowerBase"/>构造函数中创建。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </param>
|
/// </param>
|
||||||
|
@ -43,12 +43,12 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 事件字典的Key为事件名称,名称为RT中注册的Bool型数据,通过DATA.Poll访问。
|
/// 事件字典的Key为事件名称,名称为RT中注册的Bool型数据,通过DATA.Poll访问。
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// 事件动作为<see cref="STEventAction"/>动作列表,表示当上述事件为True时,指定的信号塔组件执行的动作。
|
/// 事件动作为<see cref="STAction"/>动作列表,表示当上述事件为True时,指定的信号塔组件执行的动作。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </param>
|
/// </param>
|
||||||
public void ParseEvents(Dictionary<LightType, SignalTowerPartBase> dicLights, out Dictionary<string, List<STEventAction>> events)
|
public void ParseEvents(Dictionary<STLightTypes, SignalTowerLightBase> dicLights, out Dictionary<string, List<STAction>> events)
|
||||||
{
|
{
|
||||||
events = new Dictionary<string, List<STEventAction>>();
|
events = new Dictionary<string, List<STAction>>();
|
||||||
|
|
||||||
foreach (var stEvent in Events)
|
foreach (var stEvent in Events)
|
||||||
{
|
{
|
||||||
|
@ -57,24 +57,24 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// 字典中创建一个事件项目
|
// 字典中创建一个事件项目
|
||||||
events[stEvent.Name] = new List<STEventAction>();
|
events[stEvent.Name] = new List<STAction>();
|
||||||
|
|
||||||
// 解析当前事件执行的动作
|
// 解析当前事件执行的动作
|
||||||
foreach (LightType light in Enum.GetValues(typeof(LightType)))
|
foreach (STLightTypes light in Enum.GetValues(typeof(STLightTypes)))
|
||||||
{
|
{
|
||||||
var strStatus = stEvent.GetType().GetProperty(light.ToString())?.GetValue(stEvent)?.ToString().ToLower();
|
var strStatus = stEvent.GetType().GetProperty(light.ToString())?.GetValue(stEvent)?.ToString().ToLower();
|
||||||
if (!string.IsNullOrEmpty(strStatus))
|
if (!string.IsNullOrEmpty(strStatus))
|
||||||
{
|
{
|
||||||
var status = TowerLightStatus.Unknown;
|
var status = SignalTowerActions.Unknown;
|
||||||
STBlinkPattern blinkPattern = null;
|
STBlinkPattern blinkPattern = null;
|
||||||
|
|
||||||
if (strStatus.Contains(TowerLightStatus.On.ToString().ToLower()))
|
if (strStatus.Contains(SignalTowerActions.On.ToString().ToLower()))
|
||||||
{
|
{
|
||||||
status = TowerLightStatus.On;
|
status = SignalTowerActions.On;
|
||||||
}
|
}
|
||||||
else if (strStatus.Contains(TowerLightStatus.Off.ToString().ToLower()))
|
else if (strStatus.Contains(SignalTowerActions.Off.ToString().ToLower()))
|
||||||
{
|
{
|
||||||
status = TowerLightStatus.Off;
|
status = SignalTowerActions.Off;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -91,11 +91,11 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status = TowerLightStatus.Customized;
|
status = SignalTowerActions.Customized;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dicLights.TryGetValue(light, out var part))
|
if(dicLights.TryGetValue(light, out var part))
|
||||||
events[stEvent.Name].Add(new STEventAction(stEvent.Name, part, status, blinkPattern));
|
events[stEvent.Name].Add(new STAction(stEvent.Name, part, status, blinkPattern));
|
||||||
else
|
else
|
||||||
LOG.Error($"Unable to find signal tower part {light} from STEvent config file.");
|
LOG.Error($"Unable to find signal tower part {light} from STEvent config file.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public enum TowerLightStatus
|
public enum SignalTowerActions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 使用STEvents配置文件中配置的工作模式模板
|
/// 使用STEvents配置文件中配置的工作模式模板
|
|
@ -13,8 +13,8 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
using DicEventActions = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<MECF.Framework.Common.Device.Bases.STEventAction>>;
|
using DictEvent = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<MECF.Framework.Common.Device.Bases.STAction>>;
|
||||||
using DicLightActions = System.Collections.Generic.Dictionary<MECF.Framework.Common.Device.Bases.LightType,MECF.Framework.Common.Device.Bases.STEventAction>;
|
using DictActionsPerLight = System.Collections.Generic.Dictionary<MECF.Framework.Common.Device.Bases.STLightTypes, MECF.Framework.Common.Device.Bases.STAction>;
|
||||||
|
|
||||||
namespace MECF.Framework.Common.Device.Bases
|
namespace MECF.Framework.Common.Device.Bases
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,11 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected const string KEY_PATTERN_JOB_DONE = "JobDone";
|
protected const string KEY_PATTERN_JOB_DONE = "JobDone";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 信号灯字典。
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<STLightTypes, SignalTowerLightBase> _dictStLights;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否关闭蜂鸣器输出。
|
/// 是否关闭蜂鸣器输出。
|
||||||
/// <value>True:蜂鸣器被手动关闭,满足事件条件也不要打开蜂鸣器。</value>
|
/// <value>True:蜂鸣器被手动关闭,满足事件条件也不要打开蜂鸣器。</value>
|
||||||
|
@ -48,7 +53,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// 内容改动后,会重新创建该字典,此时有可能Monitor()方法正在使用此字典。
|
/// 内容改动后,会重新创建该字典,此时有可能Monitor()方法正在使用此字典。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private DicEventActions _dicPreDefinedStEvents;
|
private DictEvent _dictPreDefinedEvents;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信号塔扩展事件字典。
|
/// 信号塔扩展事件字典。
|
||||||
|
@ -56,28 +61,23 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// 除STEvents配置中预设的事件外,还有一类事件通常由RT触发,这类事件也需要参与三色灯输出状态判断。
|
/// 除STEvents配置中预设的事件外,还有一类事件通常由RT触发,这类事件也需要参与三色灯输出状态判断。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly DicEventActions _dicRtGeneratedStEvents;
|
private readonly DictEvent _dictDynamicSTLightActions;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 信号塔中组件字典。
|
|
||||||
/// </summary>
|
|
||||||
private readonly Dictionary<LightType, SignalTowerPartBase> _dicStParts;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信号塔组件动作字典。
|
/// 信号塔组件动作字典。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<LightType, STEventAction> _dicMergedActions;
|
private DictActionsPerLight _dictSTLightActions;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上一次Monitor周期触发的事件列表。
|
/// 上一次Monitor周期触发的事件列表。
|
||||||
/// 用于下一次Monitor周期判断是否有新的事件产生,已解决蜂鸣器被手动关闭后,如果未按下Reset,则下次新事件产生时,无法响蜂鸣器的问题。
|
/// 用于下一次Monitor周期判断是否有新的事件产生,已解决蜂鸣器被手动关闭后,如果未按下Reset,则下次新事件产生时,无法响蜂鸣器的问题。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<string> _lastEventsWithBuzzer = new List<string>();
|
private readonly List<string> _lastEventsWithBuzzer = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// STEvents配置文件解析对象。
|
/// STEvents配置文件解析对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private STEvents _originStEvents;
|
private STEvents _eventsFileLoader;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -88,12 +88,14 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="module">当前模组名称。</param>
|
/// <param name="module">当前模组名称。</param>
|
||||||
/// <param name="node">设备配置文件。</param>
|
/// <param name="node">设备配置文件。</param>
|
||||||
|
/// <param name="dictStLightActions"></param>
|
||||||
/// <param name="ioModule">所属Module的名称。</param>
|
/// <param name="ioModule">所属Module的名称。</param>
|
||||||
public SignalTowerBase(string module, XmlElement node, string ioModule = "")
|
public SignalTowerBase(string module, XmlElement node, string ioModule = "")
|
||||||
: base(module, node, ioModule)
|
: base(module, node, ioModule)
|
||||||
{
|
{
|
||||||
_dicStParts = new Dictionary<LightType, SignalTowerPartBase>();
|
_dictSTLightActions = new();
|
||||||
_dicRtGeneratedStEvents = new ();
|
_dictStLights = new Dictionary<STLightTypes, SignalTowerLightBase>();
|
||||||
|
_dictDynamicSTLightActions = new ();
|
||||||
|
|
||||||
var doRedLight = ParseDoNode("doRed", node, ioModule);
|
var doRedLight = ParseDoNode("doRed", node, ioModule);
|
||||||
var doYellowLight = ParseDoNode("doYellow", node, ioModule);
|
var doYellowLight = ParseDoNode("doYellow", node, ioModule);
|
||||||
|
@ -116,27 +118,27 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
Debug.Assert(doBuzzer != null, "DO RedLight is not valid");
|
Debug.Assert(doBuzzer != null, "DO RedLight is not valid");
|
||||||
|
|
||||||
// 创建三色灯控制元件。
|
// 创建三色灯控制元件。
|
||||||
CreateSignalPart(LightType.Red, doRedLight);
|
CreateSTLight(STLightTypes.Red, doRedLight);
|
||||||
CreateSignalPart(LightType.Yellow, doYellowLight);
|
CreateSTLight(STLightTypes.Yellow, doYellowLight);
|
||||||
CreateSignalPart(LightType.Green, doGreenLight);
|
CreateSTLight(STLightTypes.Green, doGreenLight);
|
||||||
CreateSignalPart(LightType.Blue, doBlueLight);
|
CreateSTLight(STLightTypes.Blue, doBlueLight);
|
||||||
CreateSignalPart(LightType.White, doWhiteLight);
|
CreateSTLight(STLightTypes.White, doWhiteLight);
|
||||||
CreateSignalPart(LightType.Buzzer, doBuzzer, aoBuzzerBlinkFreq);
|
CreateSTLight(STLightTypes.Buzzer, doBuzzer, aoBuzzerBlinkFreq);
|
||||||
CreateSignalPart(LightType.Buzzer1, doBuzzer1);
|
CreateSTLight(STLightTypes.Buzzer1, doBuzzer1);
|
||||||
CreateSignalPart(LightType.Buzzer2, doBuzzer2);
|
CreateSTLight(STLightTypes.Buzzer2, doBuzzer2);
|
||||||
CreateSignalPart(LightType.Buzzer3, doBuzzer3);
|
CreateSTLight(STLightTypes.Buzzer3, doBuzzer3);
|
||||||
CreateSignalPart(LightType.Buzzer4, doBuzzer4);
|
CreateSTLight(STLightTypes.Buzzer4, doBuzzer4);
|
||||||
CreateSignalPart(LightType.Buzzer5, doBuzzer5);
|
CreateSTLight(STLightTypes.Buzzer5, doBuzzer5);
|
||||||
|
|
||||||
// 添加文件到监视器,当文件内容发生变化时重新加载配置。
|
// 添加文件到监视器,当文件内容发生变化时重新加载配置。
|
||||||
var fullFn = PathManager.GetCfgDir() + eventFile;
|
var fullFn = PathManager.GetCfgDir() + eventFile;
|
||||||
FileSystemWatcherManager.Instance.Register(fullFn, fn =>
|
FileSystemWatcherManager.Instance.Register(fullFn, fn =>
|
||||||
{
|
{
|
||||||
ParseSignalTowerEvent(fn);
|
ParseSTEvent(fn);
|
||||||
});
|
});
|
||||||
|
|
||||||
//解析三色灯Event
|
//解析三色灯Event
|
||||||
ParseSignalTowerEvent(fullFn);
|
ParseSTEvent(fullFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -152,17 +154,17 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
DeviceName = Name,
|
DeviceName = Name,
|
||||||
DeviceSchematicId = DeviceID,
|
DeviceSchematicId = DeviceID,
|
||||||
DisplayName = Display,
|
DisplayName = Display,
|
||||||
IsGreenLightOn = GetSignalTowerPartValue(LightType.Green),
|
IsGreenLightOn = GetSignalTowerPartValue(STLightTypes.Green),
|
||||||
IsRedLightOn = GetSignalTowerPartValue(LightType.Red),
|
IsRedLightOn = GetSignalTowerPartValue(STLightTypes.Red),
|
||||||
IsYellowLightOn = GetSignalTowerPartValue(LightType.Yellow),
|
IsYellowLightOn = GetSignalTowerPartValue(STLightTypes.Yellow),
|
||||||
IsBlueLightOn = GetSignalTowerPartValue(LightType.Blue),
|
IsBlueLightOn = GetSignalTowerPartValue(STLightTypes.Blue),
|
||||||
IsWhiteLightOn = GetSignalTowerPartValue(LightType.White),
|
IsWhiteLightOn = GetSignalTowerPartValue(STLightTypes.White),
|
||||||
IsBuzzerOn = GetSignalTowerPartValue(LightType.Buzzer),
|
IsBuzzerOn = GetSignalTowerPartValue(STLightTypes.Buzzer),
|
||||||
IsBuzzer1On = GetSignalTowerPartValue(LightType.Buzzer1),
|
IsBuzzer1On = GetSignalTowerPartValue(STLightTypes.Buzzer1),
|
||||||
IsBuzzer2On = GetSignalTowerPartValue(LightType.Buzzer2),
|
IsBuzzer2On = GetSignalTowerPartValue(STLightTypes.Buzzer2),
|
||||||
IsBuzzer3On = GetSignalTowerPartValue(LightType.Buzzer3),
|
IsBuzzer3On = GetSignalTowerPartValue(STLightTypes.Buzzer3),
|
||||||
IsBuzzer4On = GetSignalTowerPartValue(LightType.Buzzer4),
|
IsBuzzer4On = GetSignalTowerPartValue(STLightTypes.Buzzer4),
|
||||||
IsBuzzer5On = GetSignalTowerPartValue(LightType.Buzzer5),
|
IsBuzzer5On = GetSignalTowerPartValue(STLightTypes.Buzzer5),
|
||||||
};
|
};
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -172,13 +174,13 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建一个信号塔元件,并添加到字典中。
|
/// 创建一个信号塔元件,并添加到字典中。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="light">信号塔元件类型,请参考<see cref="LightType"/>。</param>
|
/// <param name="light">信号塔元件类型,请参考<see cref="STLightTypes"/>。</param>
|
||||||
/// <param name="doSw">控制元件开关的DO。</param>
|
/// <param name="doSw">控制元件开关的DO。</param>
|
||||||
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
||||||
private void CreateSignalPart(LightType light, DOAccessor doSw, AOAccessor aoBlinkFreq = null)
|
private void CreateSTLight(STLightTypes light, DOAccessor doSw, AOAccessor aoBlinkFreq = null)
|
||||||
{
|
{
|
||||||
if (doSw != null)
|
if (doSw != null)
|
||||||
_dicStParts.Add(light, new SignalTowerPartBase(light, doSw, aoBlinkFreq));
|
_dictStLights.Add(light, new SignalTowerLightBase(light, doSw, aoBlinkFreq));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -186,7 +188,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileName">包含完整路径的配置文件文件名。</param>
|
/// <param name="fileName">包含完整路径的配置文件文件名。</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool ParseSignalTowerEvent(string fileName)
|
private bool ParseSTEvent(string fileName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -196,15 +198,15 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_originStEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(fileName));
|
_eventsFileLoader = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(fileName));
|
||||||
_originStEvents.ParseEvents(_dicStParts, out var events);
|
_eventsFileLoader.ParseEvents(_dictStLights, out var events);
|
||||||
if (events == null)
|
if (events == null)
|
||||||
LOG.Error("Unable to parse the signal tower events from config file.");
|
LOG.Error("Unable to parse the signal tower events from config file.");
|
||||||
|
|
||||||
lock (SyncRoot)
|
lock (SyncRoot)
|
||||||
{
|
{
|
||||||
_dicPreDefinedStEvents = events;
|
_dictPreDefinedEvents = events;
|
||||||
return _dicPreDefinedStEvents != null;
|
return _dictPreDefinedEvents != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -235,9 +237,9 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_switchBuzzerOff = false;
|
_switchBuzzerOff = false;
|
||||||
_dicRtGeneratedStEvents?.Clear();
|
_dictDynamicSTLightActions?.Clear();
|
||||||
|
|
||||||
foreach (var light in _dicStParts.Values)
|
foreach (var light in _dictStLights.Values)
|
||||||
light.Reset();
|
light.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +248,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
foreach (var light in _dicStParts.Values)
|
foreach (var light in _dictStLights.Values)
|
||||||
light.Terminate();
|
light.Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,51 +258,57 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void HandleMonitor()
|
protected override void HandleMonitor()
|
||||||
{
|
{
|
||||||
// 创建上次发生的事件列表副本
|
// 遍历所有预设的事件,决定信号塔各元件的输出状态。
|
||||||
|
MonitorEvents(out var buzzerOnEvents);
|
||||||
|
|
||||||
List<string> events1;
|
// 判断是否有新的Buzzer相关事件产生,如果有,需要复位_switchBuzzerOff状态,以重新使能蜂鸣器,解决蜂鸣器被手动关闭后,如果不按Reset,则无法重启启用的问题。
|
||||||
lock (SyncRoot)
|
var buzzerOnEventArray = buzzerOnEvents as string[] ?? buzzerOnEvents.ToArray();
|
||||||
{
|
var newBuzzerOnEvents = _lastEventsWithBuzzer.Except(buzzerOnEventArray);
|
||||||
// 遍历所有预设的事件,决定信号塔各元件的输出状态。
|
if (newBuzzerOnEvents.Any())
|
||||||
_dicMergedActions = ConvertEventsToActions(_dicPreDefinedStEvents, out events1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 遍历所有扩展的事件,决定信号塔各元件的输出状态。
|
|
||||||
_dicMergedActions = ConvertEventsToActions(_dicRtGeneratedStEvents, out var events2, _dicMergedActions, false);
|
|
||||||
|
|
||||||
// 判断是否有新事件产生,如果有,需要复位_switchBuzzerOff状态,以重新使能蜂鸣器,解决蜂鸣器被手动关闭后,如果不按Reset,则无法重启启用的问题。
|
|
||||||
var eventCombined = new List<string>(events1.Concat(events2));
|
|
||||||
var newEvents = _lastEventsWithBuzzer.Except(eventCombined);
|
|
||||||
if (newEvents.Any())
|
|
||||||
{
|
{
|
||||||
_lastEventsWithBuzzer.Clear();
|
_lastEventsWithBuzzer.Clear();
|
||||||
_lastEventsWithBuzzer.AddRange(eventCombined);
|
_lastEventsWithBuzzer.AddRange(buzzerOnEventArray);
|
||||||
_switchBuzzerOff = false;
|
_switchBuzzerOff = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置信号塔每个组件的输出。
|
// 分配每个信号灯的动作。
|
||||||
foreach (var kvp in _dicMergedActions)
|
foreach (var kvp in _dictSTLightActions)
|
||||||
{
|
{
|
||||||
var action = kvp.Value;
|
var action = kvp.Value;
|
||||||
if (action == null)
|
|
||||||
continue;
|
if (action?.Light == null)
|
||||||
|
|
||||||
if (action.StPart == null)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// 创建动作副本,因为后续可能根据_switchBuzzerOff调整输出状态,避免覆盖原配置。
|
// 创建动作副本,因为后续可能根据_switchBuzzerOff调整输出状态,避免覆盖原配置。
|
||||||
var cloned = (STEventAction)action.Clone();
|
var cloned = (STAction)action.Clone();
|
||||||
|
|
||||||
// 如果蜂鸣器被强制关闭,则将待执行动作中的状态修改为Off
|
// 如果蜂鸣器被强制关闭,则将待执行动作中的状态修改为Off
|
||||||
if (action.StPart.IsBuzzer && _switchBuzzerOff)
|
if (action.Light.IsBuzzer && _switchBuzzerOff)
|
||||||
cloned.Status = TowerLightStatus.Off;
|
cloned.Output = SignalTowerActions.Off;
|
||||||
|
|
||||||
action.StPart.SetAction(cloned);
|
action.Light.SetAction(cloned);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扫描信号塔组件状态
|
// 扫描信号塔组件状态
|
||||||
foreach (var light in _dicStParts.Values)
|
foreach (var light in _dictStLights.Values)
|
||||||
light?.Monitor();
|
{
|
||||||
|
if(light == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
light.Monitor();
|
||||||
|
|
||||||
|
// remove the cycle done action from dynamic STEvent dictionary
|
||||||
|
var currAction = light.GetAction();
|
||||||
|
if (currAction is { IsCycleDone: true }
|
||||||
|
&& _dictDynamicSTLightActions.TryGetValue(currAction.EventName, out var actions))
|
||||||
|
{
|
||||||
|
for (var i = actions.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (actions[i].LightType == light.Type)
|
||||||
|
actions.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -309,7 +317,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <param name="light">指定的信号塔元件。</param>
|
/// <param name="light">指定的信号塔元件。</param>
|
||||||
/// <param name="pattern">闪烁模式。</param>
|
/// <param name="pattern">闪烁模式。</param>
|
||||||
/// <returns>True:启动闪烁成功;False:启动闪烁失败。</returns>
|
/// <returns>True:启动闪烁成功;False:启动闪烁失败。</returns>
|
||||||
public bool Blink(LightType light, STBlinkPattern pattern)
|
public bool Blink(STLightTypes light, STBlinkPattern pattern)
|
||||||
{
|
{
|
||||||
if (pattern == null)
|
if (pattern == null)
|
||||||
{
|
{
|
||||||
|
@ -317,7 +325,11 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateRtEvent(new STEventAction("Rt Triggered Blink", _dicStParts[light], TowerLightStatus.Customized, pattern));
|
var evName = $"Manual_Blink_{light}_{Guid.NewGuid()}";
|
||||||
|
var blinkAction = new STAction(evName, _dictStLights[light], SignalTowerActions.Customized,
|
||||||
|
pattern);
|
||||||
|
|
||||||
|
CreateDynamicEvent(evName, [blinkAction]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -325,27 +337,25 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当Wafer回到Cassette后,打开蜂鸣器以指示ProcessJob结束。
|
/// 当Wafer回到Cassette后,打开蜂鸣器以指示ProcessJob结束。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reason">如果打开蜂鸣器失败,提示失败原因。</param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool SwitchOnBuzzerForJobDone(out string reason)
|
public bool AlertJobDone()
|
||||||
{
|
{
|
||||||
reason = "";
|
SignalTowerLightBase targetBuzzer = null;
|
||||||
SignalTowerPartBase targetBuzzer = null;
|
|
||||||
STBlinkPattern blinkPattern = null;
|
STBlinkPattern blinkPattern = null;
|
||||||
|
|
||||||
// 读取STEvents配置文件中的JobDone模式的配置。
|
// 读取STEvents配置文件中的JobDone模式的配置。
|
||||||
var settings = _originStEvents.PatternsSettings.FirstOrDefault(x => x.Name == KEY_PATTERN_JOB_DONE);
|
var alertPattern = _eventsFileLoader.PatternsSettings.FirstOrDefault(x => x.Name == KEY_PATTERN_JOB_DONE);
|
||||||
|
|
||||||
if (settings != null)
|
if (alertPattern != null)
|
||||||
{
|
{
|
||||||
// 解析配置中的Buzzer,如果未指定Buzzer,或指定为除Buzzer以外的信号灯,则默认使用Buzzer。
|
// 解析配置中的Buzzer,如果未指定Buzzer,或指定为除Buzzer以外的信号灯,则默认使用Buzzer。
|
||||||
var targetPart = settings.Part;
|
var targetLight = alertPattern.Part;
|
||||||
if (Enum.TryParse(targetPart, out LightType lightType)
|
if (Enum.TryParse(targetLight, out STLightTypes lightType)
|
||||||
&& _dicStParts.TryGetValue(lightType, out var buzzer)
|
&& _dictStLights.TryGetValue(lightType, out var buzzer)
|
||||||
&& buzzer.IsBuzzer)
|
&& buzzer.IsBuzzer)
|
||||||
targetBuzzer = buzzer;
|
targetBuzzer = buzzer;
|
||||||
|
|
||||||
blinkPattern = new STBlinkPattern(settings.Pattern, priority: settings.Priority, cycle: settings.Cycles);
|
blinkPattern = new STBlinkPattern(alertPattern.Pattern, priority: alertPattern.Priority, cycle: alertPattern.Cycles);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -354,10 +364,12 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
LOG.Warning($"Unable to find pre-defined pattern for {KEY_PATTERN_JOB_DONE}");
|
LOG.Warning($"Unable to find pre-defined pattern for {KEY_PATTERN_JOB_DONE}");
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateRtEvent(new STEventAction(KEY_PATTERN_JOB_DONE, targetBuzzer, TowerLightStatus.Customized, blinkPattern));
|
var buzzerAction = new STAction(KEY_PATTERN_JOB_DONE, targetBuzzer, SignalTowerActions.Customized,
|
||||||
|
blinkPattern);
|
||||||
|
CreateDynamicEvent(KEY_PATTERN_JOB_DONE, [buzzerAction]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 打开或关闭蜂鸣器。
|
/// 打开或关闭蜂鸣器。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -382,9 +394,9 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 合并信号事件。
|
/// 获取优先级更高的STAction。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 根据<see cref="STEventAction.Status"/>的优先级决定执行的动作。
|
/// 根据<see cref="STAction.Output"/>的优先级决定执行的动作。
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// 此属性的数值越小,表示优先级越高。
|
/// 此属性的数值越小,表示优先级越高。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
@ -392,7 +404,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <param name="currentAction">当前输出状态。</param>
|
/// <param name="currentAction">当前输出状态。</param>
|
||||||
/// <param name="nextAction">期望的输出状态。</param>
|
/// <param name="nextAction">期望的输出状态。</param>
|
||||||
/// <returns>合并后的信号灯输出状态。</returns>
|
/// <returns>合并后的信号灯输出状态。</returns>
|
||||||
private STEventAction MergeAction(STEventAction currentAction, STEventAction nextAction)
|
private STAction PickPriorAction(STAction currentAction, STAction nextAction)
|
||||||
{
|
{
|
||||||
if (currentAction == null)
|
if (currentAction == null)
|
||||||
return nextAction;
|
return nextAction;
|
||||||
|
@ -400,14 +412,14 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
return currentAction;
|
return currentAction;
|
||||||
|
|
||||||
// 获取当前动作的优先级
|
// 获取当前动作的优先级
|
||||||
var curPrior = currentAction.Status == TowerLightStatus.Customized
|
var curPrior = currentAction.Output == SignalTowerActions.Customized
|
||||||
? currentAction.BlinkPattern.Priority
|
? currentAction.BlinkPattern.Priority
|
||||||
: (int)currentAction.Status;
|
: (int)currentAction.Output;
|
||||||
|
|
||||||
// 获取下一个动作的优先级
|
// 获取下一个动作的优先级
|
||||||
var nextPrior = nextAction.Status == TowerLightStatus.Customized
|
var nextPrior = nextAction.Output == SignalTowerActions.Customized
|
||||||
? nextAction.BlinkPattern.Priority
|
? nextAction.BlinkPattern.Priority
|
||||||
: (int)nextAction.Status;
|
: (int)nextAction.Output;
|
||||||
|
|
||||||
|
|
||||||
return curPrior < nextPrior ? currentAction : nextAction;
|
return curPrior < nextPrior ? currentAction : nextAction;
|
||||||
|
@ -418,104 +430,115 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="light"></param>
|
/// <param name="light"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool GetSignalTowerPartValue(LightType light)
|
private bool GetSignalTowerPartValue(STLightTypes light)
|
||||||
{
|
{
|
||||||
if (_dicStParts.TryGetValue(light, out var part))
|
if (_dictStLights.TryGetValue(light, out var part))
|
||||||
return part.GetValue();
|
return part.GetValue();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取RT中已触发的事件列表。
|
/// 从RT拉取已发生的STEvent列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static DicEventActions PollRtAlarms(DicEventActions dicEvents)
|
private static DictEvent PollRaisedEvents(DictEvent dicEvents)
|
||||||
{
|
{
|
||||||
if (dicEvents == null)
|
if (dicEvents == null)
|
||||||
return new DicEventActions();
|
return new();
|
||||||
|
|
||||||
var data = dicEvents.Keys.ToList();
|
var events = dicEvents.Keys.ToList();
|
||||||
var polled = DATA.PollData(data);
|
var data = DATA.PollData(events);
|
||||||
|
var raisedEvents = data.Where(x => x.Value is true).Select(x => x.Key).ToList();
|
||||||
|
|
||||||
var eventTriggered = polled.Where(x => x.Value is true).Select(x => x.Key).ToList();
|
return dicEvents.Where(x => raisedEvents.Contains(x.Key)).ToDictionary(x => x.Key, v => v.Value);
|
||||||
|
|
||||||
return dicEvents.Where(x => eventTriggered.Contains(x.Key)).ToDictionary(x => x.Key, v => v.Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更具RT当前状态合并所有事件的动作,决定信号塔组件的输出状态。
|
/// 监视STEvent.xml中定义的事件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dicEvents">事件字典。</param>
|
/// <param name="eventsWithBuzzerOn"></param>
|
||||||
/// <param name="eventsWithBuzzerOn">返回需要触发Buzzer的事件的名称列表。</param>
|
private void MonitorEvents(out IEnumerable<string> eventsWithBuzzerOn)
|
||||||
/// <param name="initActions">信号塔组件初始动作字典。</param>
|
|
||||||
/// <param name="isPollDataNeeded">
|
|
||||||
/// 是否从RT拉去事件对应的属性值。
|
|
||||||
/// <remarks>
|
|
||||||
/// 对于<see cref="_dicRtGeneratedStEvents"/>事件列表,不需要从RT拉去数据,直接合并动作即可。
|
|
||||||
/// </remarks>
|
|
||||||
/// </param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private DicLightActions ConvertEventsToActions(DicEventActions dicEvents, out List<string> eventsWithBuzzerOn, DicLightActions initActions = null, bool isPollDataNeeded = true)
|
|
||||||
{
|
{
|
||||||
// 创建初始动作字典
|
lock (SyncRoot)
|
||||||
initActions ??= _dicStParts.ToDictionary(
|
|
||||||
x => x.Key,
|
|
||||||
v => new STEventAction("", v.Value, TowerLightStatus.Off));
|
|
||||||
|
|
||||||
// 对于STEvent配置文件中的事件,我们只需要关注那些条件为True的事件。
|
|
||||||
// 创建一个临时字典,筛选条件为True的事件,或直接使用_dicRtGeneratedEvents事件字典。
|
|
||||||
var dicEventsTmp = dicEvents;
|
|
||||||
|
|
||||||
// 需要从RT拉取事件状态
|
|
||||||
if (isPollDataNeeded)
|
|
||||||
dicEventsTmp = PollRtAlarms(dicEvents);
|
|
||||||
|
|
||||||
// 保存触发的事件名称列表。
|
|
||||||
var eventsBuzzerNotOff = dicEventsTmp
|
|
||||||
.Where(x => x.Value
|
|
||||||
.Any(v => v.StPart.IsBuzzer && v.Status != TowerLightStatus.Off))
|
|
||||||
.Select(x => x.Key);
|
|
||||||
|
|
||||||
eventsWithBuzzerOn = new List<string>(eventsBuzzerNotOff);
|
|
||||||
|
|
||||||
// 遍历所有预设的事件,决定信号塔各元件的输出状态。
|
|
||||||
foreach (var stEvent in dicEventsTmp)
|
|
||||||
{
|
{
|
||||||
foreach (var newAction in stEvent.Value)
|
// Clear previous actions
|
||||||
|
_dictSTLightActions.Clear();
|
||||||
|
|
||||||
|
// Poll raised events of RT
|
||||||
|
var raisedEvents = PollRaisedEvents(_dictPreDefinedEvents);
|
||||||
|
|
||||||
|
// Create dictionary '_dictSTLightActions'
|
||||||
|
AssignSTActions(raisedEvents);
|
||||||
|
AssignSTActions(_dictDynamicSTLightActions);
|
||||||
|
|
||||||
|
// Get a list of events related to turning on a buzzer
|
||||||
|
var buzzerOnEv1 = GetBuzzerOnEvents(raisedEvents).ToArray();
|
||||||
|
var buzzerOnEv2 = GetBuzzerOnEvents(_dictDynamicSTLightActions).ToArray();
|
||||||
|
|
||||||
|
eventsWithBuzzerOn = buzzerOnEv1.Concat(buzzerOnEv2.Except(buzzerOnEv1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据已发生的STEvent分配各个信号灯的动作。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="raisedEvents"></param>
|
||||||
|
private void AssignSTActions(DictEvent raisedEvents)
|
||||||
|
{
|
||||||
|
foreach (var stEvent in raisedEvents)
|
||||||
|
{
|
||||||
|
foreach (var action in stEvent.Value)
|
||||||
{
|
{
|
||||||
if (!_dicStParts.TryGetValue(newAction.StPart.Light, out var stPart))
|
// Maybe the target light of the action is not defined
|
||||||
|
if (!_dictStLights.ContainsKey(action.LightType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// 根据当前设备状态,判断下一步信号组件的输出动作是什么
|
// Make it easier to access dictionaries using the key
|
||||||
var mergedAction = MergeAction(initActions[stPart.Light], newAction);
|
var light = action.LightType;
|
||||||
|
|
||||||
initActions[stPart.Light] = mergedAction;
|
// Determine the action of light according to the event raised
|
||||||
|
if (!_dictSTLightActions.TryGetValue(light, out var oldAction))
|
||||||
|
_dictSTLightActions.Add(light, action);
|
||||||
|
else
|
||||||
|
_dictSTLightActions[light] = PickPriorAction(oldAction, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return initActions;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建一个自定义的RT事件,以驱动指定的信号塔组件。
|
/// 获取需要打开Buzzer的事件的名称。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="events"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private IEnumerable<string> GetBuzzerOnEvents(DictEvent events)
|
||||||
|
{
|
||||||
|
// create a list for the events operating the buzzer
|
||||||
|
var buzzerOnEvents = events
|
||||||
|
.Where(x => x.Value
|
||||||
|
.Any(v => v.Light.IsBuzzer && v.Output != SignalTowerActions.Off))
|
||||||
|
.Select(x => x.Key);
|
||||||
|
|
||||||
|
return buzzerOnEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个动态RT事件,以驱动指定的信号塔组件。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 自动创建Guid作为事件的Key,以和STEvent配置字典的格式保持一致,以为Monitor方法中需要同时对这两个字典处理;格式的统一有助于统一处理任务的逻辑。
|
/// 自动创建Guid作为事件的Key,以和STEvent配置字典的格式保持一致,以为Monitor方法中需要同时对这两个字典处理;格式的统一有助于统一处理任务的逻辑。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="eventName"></param>
|
||||||
/// <param name="actions">该事件执行的动作列表。
|
/// <param name="actions">该事件执行的动作列表。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 列表的每一个元素对应一个信号塔组件需执行的动作。
|
/// 列表的每一个元素对应一个信号塔组件需执行的动作。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </param>
|
/// </param>
|
||||||
|
private void CreateDynamicEvent(string eventName, List<STAction> actions)
|
||||||
private void CreateRtEvent(params STEventAction[] actions)
|
|
||||||
{
|
{
|
||||||
_dicRtGeneratedStEvents.Add(Guid.NewGuid().ToString(), actions.ToList());
|
_dictDynamicSTLightActions[eventName] = actions;
|
||||||
SwitchOffBuzzer(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,18 @@ using Aitex.Core.RT.Device;
|
||||||
using Aitex.Core.RT.IOCore;
|
using Aitex.Core.RT.IOCore;
|
||||||
using Aitex.Core.RT.Log;
|
using Aitex.Core.RT.Log;
|
||||||
using Aitex.Core.Util;
|
using Aitex.Core.Util;
|
||||||
using SciChart.Charting2D.Interop;
|
using BlinkDataType = System.Collections.Generic.KeyValuePair<MECF.Framework.Common.Device.Bases.SignalTowerActions, uint>;
|
||||||
using BlinkDataType = System.Collections.Generic.KeyValuePair<MECF.Framework.Common.Device.Bases.TowerLightStatus, uint>;
|
|
||||||
|
|
||||||
namespace MECF.Framework.Common.Device.Bases
|
namespace MECF.Framework.Common.Device.Bases
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信号塔元件对象,包含灯和蜂鸣器。
|
/// 信号塔元件对象,包含灯和蜂鸣器。
|
||||||
/// 受支持的元件请参考<see cref="LightType"/>。
|
/// 受支持的元件请参考<see cref="STLightTypes"/>。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 信号塔元件的Blink模式基于一个简单的Switch-Case状态机实现。
|
/// 信号塔元件的Blink模式基于一个简单的Switch-Case状态机实现。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SignalTowerPartBase : BaseDevice, IDevice
|
public class SignalTowerLightBase : BaseDevice, IDevice
|
||||||
{
|
{
|
||||||
#region Variables
|
#region Variables
|
||||||
|
|
||||||
|
@ -36,8 +35,8 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
|
|
||||||
private DOAccessor _doLight;
|
private DOAccessor _doLight;
|
||||||
private AOAccessor _aoBlinkFreqHz;
|
private AOAccessor _aoBlinkFreqHz;
|
||||||
private readonly LightType _lightType;
|
private readonly STLightTypes _lightType;
|
||||||
private STEventAction _action;
|
private STAction _action;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 闪烁次数计数器。
|
/// 闪烁次数计数器。
|
||||||
|
@ -62,10 +61,10 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构建信号塔元件对象的实例。
|
/// 构建信号塔元件对象的实例。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="light">信号塔元件类型,请参考<see cref="LightType"/>。</param>
|
/// <param name="light">信号塔元件类型,请参考<see cref="STLightTypes"/>。</param>
|
||||||
/// <param name="doSwitch">控制元件开关的DO。</param>
|
/// <param name="doSwitch">控制元件开关的DO。</param>
|
||||||
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
||||||
public SignalTowerPartBase(LightType light, DOAccessor doSwitch, AOAccessor aoBlinkFreq)
|
public SignalTowerLightBase(STLightTypes light, DOAccessor doSwitch, AOAccessor aoBlinkFreq)
|
||||||
{
|
{
|
||||||
_lightType = light;
|
_lightType = light;
|
||||||
_doLight = doSwitch;
|
_doLight = doSwitch;
|
||||||
|
@ -82,7 +81,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回信号塔元件类型。
|
/// 返回信号塔元件类型。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LightType Light => _lightType;
|
public STLightTypes Type => _lightType;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -117,13 +116,13 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 如果信号塔元件的状态已经转为Off,但状态机没有进入Idle,说明可能人为取消了信号,需要复位状态机。
|
// 如果信号塔元件的状态已经转为Off,但状态机没有进入Idle,说明可能人为取消了信号,需要复位状态机。
|
||||||
if (_action.Status == TowerLightStatus.Off && _blinkStage != FsmStateBlink.Idle)
|
if (_action.Output == SignalTowerActions.Off && _blinkStage != FsmStateBlink.Idle)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果动作状态指定使用自定义模式,并且循环次数未用完,则根据Pattern进行闪烁
|
// 如果动作状态指定使用自定义模式,并且循环次数未用完,则根据Pattern进行闪烁
|
||||||
if (_action.Status == TowerLightStatus.Customized && _blinkCycleDownCounter > 0)
|
if (_action.Output == SignalTowerActions.Customized && _blinkCycleDownCounter > 0)
|
||||||
{
|
{
|
||||||
switch (_blinkStage)
|
switch (_blinkStage)
|
||||||
{
|
{
|
||||||
|
@ -155,9 +154,9 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
|
|
||||||
_nextBlinkData = _qBlinkData.Dequeue();
|
_nextBlinkData = _qBlinkData.Dequeue();
|
||||||
|
|
||||||
if (_nextBlinkData.Key == TowerLightStatus.On)
|
if (_nextBlinkData.Key == SignalTowerActions.On)
|
||||||
_blinkStage = FsmStateBlink.PrepareOn;
|
_blinkStage = FsmStateBlink.PrepareOn;
|
||||||
else if (_nextBlinkData.Key == TowerLightStatus.Off)
|
else if (_nextBlinkData.Key == SignalTowerActions.Off)
|
||||||
_blinkStage = FsmStateBlink.PrepareOff;
|
_blinkStage = FsmStateBlink.PrepareOff;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -213,8 +212,9 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
{
|
{
|
||||||
// Blink循环结束,关闭输出
|
// Blink循环结束,关闭输出
|
||||||
_doLight.Value = false;
|
_doLight.Value = false;
|
||||||
_action.Status = TowerLightStatus.Off;
|
_action.Output = SignalTowerActions.Off;
|
||||||
_blinkStage = FsmStateBlink.Cleanup;
|
_blinkStage = FsmStateBlink.Cleanup;
|
||||||
|
_action.IsCycleDone = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -245,7 +245,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
/// 获取信号塔元件当前正在执行的动作。
|
/// 获取信号塔元件当前正在执行的动作。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public STEventAction GetAction()
|
public STAction GetAction()
|
||||||
{
|
{
|
||||||
return _action;
|
return _action;
|
||||||
}
|
}
|
||||||
|
@ -261,10 +261,10 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置信号塔元件动作。
|
/// 设置信号塔元件动作。
|
||||||
/// <para>请参考<see cref="TowerLightStatus"/>枚举获取支持的动作类型。</para>
|
/// <para>请参考<see cref="SignalTowerActions"/>枚举获取支持的动作类型。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">信号灯的动作。</param>
|
/// <param name="action">信号灯的动作。</param>
|
||||||
public void SetAction(STEventAction action)
|
public void SetAction(STAction action)
|
||||||
{
|
{
|
||||||
if (action == null)
|
if (action == null)
|
||||||
{
|
{
|
||||||
|
@ -288,20 +288,20 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行动作
|
// 执行动作
|
||||||
switch (_action.Status)
|
switch (_action.Output)
|
||||||
{
|
{
|
||||||
case TowerLightStatus.On:
|
case SignalTowerActions.On:
|
||||||
_blinkCycleDownCounter = 0;
|
_blinkCycleDownCounter = 0;
|
||||||
_doLight.Value = true;
|
_doLight.Value = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TowerLightStatus.Off:
|
case SignalTowerActions.Off:
|
||||||
_blinkCycleDownCounter = 0;
|
_blinkCycleDownCounter = 0;
|
||||||
_doLight.Value = false;
|
_doLight.Value = false;
|
||||||
Reset(); // 复位状态机
|
Reset(); // 复位状态机
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TowerLightStatus.Customized:
|
case SignalTowerActions.Customized:
|
||||||
// 当工作在闪烁状态时,如果没有指定闪烁模式,则创建一个默认模式。
|
// 当工作在闪烁状态时,如果没有指定闪烁模式,则创建一个默认模式。
|
||||||
_blinkPattern = _action.BlinkPattern;
|
_blinkPattern = _action.BlinkPattern;
|
||||||
_blinkPattern ??= new STBlinkPattern();
|
_blinkPattern ??= new STBlinkPattern();
|
||||||
|
@ -320,7 +320,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
if (!STBlinkPattern.GetBlinkData(_blinkPattern, out _blinkData, out var reason))
|
if (!STBlinkPattern.GetBlinkData(_blinkPattern, out _blinkData, out var reason))
|
||||||
{
|
{
|
||||||
// 如果解析闪烁数据,如果解析错误,使用默认的闪烁模式。
|
// 如果解析闪烁数据,如果解析错误,使用默认的闪烁模式。
|
||||||
LOG.Error($"Unable to set {Light} to {action}, {reason}");
|
LOG.Error($"Unable to set {Type} to {action}, {reason}");
|
||||||
STBlinkPattern.GetBlinkData(STBlinkPattern.GetDefaultPattern(), out _blinkData, out _);
|
STBlinkPattern.GetBlinkData(STBlinkPattern.GetDefaultPattern(), out _blinkData, out _);
|
||||||
Debug.Assert(_blinkData != null);
|
Debug.Assert(_blinkData != null);
|
||||||
}
|
}
|
||||||
|
@ -332,8 +332,8 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TowerLightStatus.Unknown:
|
case SignalTowerActions.Unknown:
|
||||||
LOG.Error($"{Light} Undefined output status");
|
LOG.Error($"{Type} Undefined output status");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -350,7 +350,7 @@ namespace MECF.Framework.Common.Device.Bases
|
||||||
_blinkStage = FsmStateBlink.Idle;
|
_blinkStage = FsmStateBlink.Idle;
|
||||||
|
|
||||||
if (_action != null)
|
if (_action != null)
|
||||||
_action.Status = TowerLightStatus.Off;
|
_action.Output = SignalTowerActions.Off;
|
||||||
|
|
||||||
_blinkCycleDownCounter = 0;
|
_blinkCycleDownCounter = 0;
|
||||||
_doLight.Value = false;
|
_doLight.Value = false;
|
|
@ -18,7 +18,7 @@ namespace MECF.Framework.Common.OperationCenter
|
||||||
[ServiceKnownType(typeof(WaferStatus))]
|
[ServiceKnownType(typeof(WaferStatus))]
|
||||||
[ServiceKnownType(typeof(TransferInfo[]))]
|
[ServiceKnownType(typeof(TransferInfo[]))]
|
||||||
[ServiceKnownType(typeof(TransferInfo))]
|
[ServiceKnownType(typeof(TransferInfo))]
|
||||||
[ServiceKnownType(typeof(TowerLightStatus))]
|
[ServiceKnownType(typeof(SignalTowerActions))]
|
||||||
[ServiceKnownType(typeof(short[]))]
|
[ServiceKnownType(typeof(short[]))]
|
||||||
[ServiceKnownType(typeof(bool[]))]
|
[ServiceKnownType(typeof(bool[]))]
|
||||||
[ServiceKnownType(typeof(string[]))]
|
[ServiceKnownType(typeof(string[]))]
|
||||||
|
|
|
@ -5,20 +5,20 @@ namespace MECF.Framework.RT.EquipmentLibrary.Devices
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 信号塔元件对象,包含灯和蜂鸣器。
|
/// 信号塔元件对象,包含灯和蜂鸣器。
|
||||||
/// 受支持的元件请参考<see cref="LightType"/>。
|
/// 受支持的元件请参考<see cref="STLightTypes"/>。
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// 信号塔元件的Blink模式基于一个简单的Switch-Case状态机实现。
|
/// 信号塔元件的Blink模式基于一个简单的Switch-Case状态机实现。
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IoSignalTowerPart : SignalTowerPartBase
|
public class IoSignalTowerLight : SignalTowerLightBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造IoSignalTowerPart对象。
|
/// 构造IoSignalTowerPart对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="light">信号塔元件类型,请参考<see cref="LightType"/>。</param>
|
/// <param name="light">信号塔元件类型,请参考<see cref="STLightTypes"/>。</param>
|
||||||
/// <param name="doSw">控制元件开关的DO。</param>
|
/// <param name="doSw">控制元件开关的DO。</param>
|
||||||
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
/// <param name="aoBlinkFreq">控制Blink频率的AO。</param>
|
||||||
public IoSignalTowerPart(LightType light, DOAccessor doSw, AOAccessor aoBlinkFreq)
|
public IoSignalTowerLight(STLightTypes light, DOAccessor doSw, AOAccessor aoBlinkFreq)
|
||||||
: base(light, doSw, aoBlinkFreq)
|
: base(light, doSw, aoBlinkFreq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems
|
||||||
bool MoveToReadyPut(ModuleName chamber, int slot, Hand hand, out string reason);
|
bool MoveToReadyPut(ModuleName chamber, int slot, Hand hand, out string reason);
|
||||||
|
|
||||||
//signal tower
|
//signal tower
|
||||||
bool SetSignalLight(LightType type, TowerLightStatus state, out string reason);
|
bool SetSignalLight(STLightTypes type, SignalTowerActions state, out string reason);
|
||||||
|
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
bool SetLoadPortLight(ModuleName chamber, Indicator light, IndicatorState state);
|
bool SetLoadPortLight(ModuleName chamber, Indicator light, IndicatorState state);
|
||||||
|
|
|
@ -421,7 +421,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
|
||||||
return _connection.Execute(new RorzeEfemHandlerGoto(this, chamber, slot, hand, false), out reason);
|
return _connection.Execute(new RorzeEfemHandlerGoto(this, chamber, slot, hand, false), out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetSignalLight(LightType type, TowerLightStatus state, out string reason)
|
public bool SetSignalLight(STLightTypes type, SignalTowerActions state, out string reason)
|
||||||
{
|
{
|
||||||
if (_connection == null || !_connection.IsConnected || !IsCommunicationReady)
|
if (_connection == null || !_connection.IsConnected || !IsCommunicationReady)
|
||||||
{
|
{
|
||||||
|
|
|
@ -752,7 +752,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
|
||||||
MutexId = -1;
|
MutexId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RorzeEfemHandlerSigout(RorzeEfem device, ModuleName module, LightType type, TowerLightStatus state)
|
public RorzeEfemHandlerSigout(RorzeEfem device, ModuleName module, STLightTypes type, SignalTowerActions state)
|
||||||
: base(device, module, RorzeEfemMessageType.SET, RorzeEfemBasicMessage.SIGOUT, BuildParameter(module, type, state), false)
|
: base(device, module, RorzeEfemMessageType.SET, RorzeEfemBasicMessage.SIGOUT, BuildParameter(module, type, state), false)
|
||||||
{
|
{
|
||||||
Name = $"Set Signal Tower";
|
Name = $"Set Signal Tower";
|
||||||
|
@ -780,30 +780,30 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
|
||||||
return $"{par1}/{par2}/{par3}";
|
return $"{par1}/{par2}/{par3}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string BuildParameter(ModuleName target, LightType type, TowerLightStatus state)
|
public static string BuildParameter(ModuleName target, STLightTypes type, SignalTowerActions state)
|
||||||
{
|
{
|
||||||
if (type == LightType.Buzzer)
|
if (type == STLightTypes.Buzzer)
|
||||||
{
|
{
|
||||||
type = state == TowerLightStatus.Customized ? LightType.Buzzer2 : LightType.Buzzer1;
|
type = state == SignalTowerActions.Customized ? STLightTypes.Buzzer2 : STLightTypes.Buzzer1;
|
||||||
state = state == TowerLightStatus.Off ? TowerLightStatus.Off : TowerLightStatus.On;
|
state = state == SignalTowerActions.Off ? SignalTowerActions.Off : SignalTowerActions.On;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<LightType, string> mapLightType = new Dictionary<LightType, string>()
|
Dictionary<STLightTypes, string> mapLightType = new Dictionary<STLightTypes, string>()
|
||||||
{
|
{
|
||||||
{LightType.Red, "RED"},
|
{STLightTypes.Red, "RED"},
|
||||||
{LightType.Yellow, "YELLOW"},
|
{STLightTypes.Yellow, "YELLOW"},
|
||||||
{LightType.Green, "GREEN"},
|
{STLightTypes.Green, "GREEN"},
|
||||||
{LightType.Blue, "BLUE"},
|
{STLightTypes.Blue, "BLUE"},
|
||||||
{LightType.White, "WHITE"},
|
{STLightTypes.White, "WHITE"},
|
||||||
{LightType.Buzzer1, "BUZZER1"},
|
{STLightTypes.Buzzer1, "BUZZER1"},
|
||||||
{LightType.Buzzer2, "BUZZER2"},
|
{STLightTypes.Buzzer2, "BUZZER2"},
|
||||||
};
|
};
|
||||||
|
|
||||||
Dictionary<TowerLightStatus, string> mapLightState = new Dictionary<TowerLightStatus, string>()
|
Dictionary<SignalTowerActions, string> mapLightState = new Dictionary<SignalTowerActions, string>()
|
||||||
{
|
{
|
||||||
{TowerLightStatus.On, "ON"},
|
{SignalTowerActions.On, "ON"},
|
||||||
{TowerLightStatus.Off, "OFF"},
|
{SignalTowerActions.Off, "OFF"},
|
||||||
{TowerLightStatus.Customized, "BLINK"},
|
{SignalTowerActions.Customized, "BLINK"},
|
||||||
};
|
};
|
||||||
|
|
||||||
string par1 = "STOWER";
|
string par1 = "STOWER";
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
<Compile Include="Devices\IoSCR.cs" />
|
<Compile Include="Devices\IoSCR.cs" />
|
||||||
<Compile Include="Devices\IoCassette.cs" />
|
<Compile Include="Devices\IoCassette.cs" />
|
||||||
<Compile Include="Devices\IoSensor.cs" />
|
<Compile Include="Devices\IoSensor.cs" />
|
||||||
<Compile Include="Devices\IoSignalTowerPart.cs" />
|
<Compile Include="Devices\IoSignalTowerLight.cs" />
|
||||||
<Compile Include="Devices\IoSignalTower.cs" />
|
<Compile Include="Devices\IoSignalTower.cs" />
|
||||||
<Compile Include="Devices\IoTC.cs" />
|
<Compile Include="Devices\IoTC.cs" />
|
||||||
<Compile Include="Devices\IoTempMeter.cs" />
|
<Compile Include="Devices\IoTempMeter.cs" />
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MECF.Framework.Common.Device.Bases.Tests
|
||||||
[Fact()]
|
[Fact()]
|
||||||
public void ParseEventsTest()
|
public void ParseEventsTest()
|
||||||
{
|
{
|
||||||
var mockDictStParts = new Mock<Dictionary<LightType, SignalTowerPartBase>>();
|
var mockDictStParts = new Mock<Dictionary<STLightTypes, SignalTowerLightBase>>();
|
||||||
var stEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(FN_STSETTINGS));
|
var stEvents = CustomXmlSerializer.Deserialize<STEvents>(new FileInfo(FN_STSETTINGS));
|
||||||
stEvents.ParseEvents(null, out var events);
|
stEvents.ParseEvents(null, out var events);
|
||||||
Assert.NotNull(events);
|
Assert.NotNull(events);
|
||||||
|
|
Loading…
Reference in New Issue