Sic.Framework/MECF.Framework.Common/MECF/Framework/Common/Device/Bases/STBlinkPattern.cs

241 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Aitex.Core.RT.Log;
using BlinkDataType = System.Collections.Generic.KeyValuePair<MECF.Framework.Common.Device.Bases.TowerLightStatus, uint>;
namespace MECF.Framework.Common.Device.Bases;
/// <summary>
/// 信号灯塔元件闪烁模式。
/// </summary>
[Serializable]
[DataContract]
public class STBlinkPattern
{
#region Variables
/// <summary>
/// 以-或.配置闪烁模式的字串正则表达式。
/// </summary>
public const string REG_PATT_BLINK_PATTERN = @"^([-\.])+$";
/// <summary>
/// 模式字符串中每个字符对应的延时时长,单位毫秒。
/// </summary>
private const uint DELAY_MS_PER_CHAR = 100;
#endregion
#region Constructors
/// <summary>
/// 构造信号灯元件闪烁模式。
/// <para>如果未指定闪烁模式,则默认开一秒,关一秒,无限循环。</para>
/// </summary>
public STBlinkPattern()
{
TotalCycles = 0;
Pattern = "----------..........";
}
/// <summary>
/// 创建信号灯塔元件闪烁模式对象的实例。
/// </summary>
/// <param name="cycle">总循环次数0或负值表示无限循环。</param>
/// <param name="pattern">
/// 闪烁模式。
/// 请参考属性<see cref="Pattern"/>以或许模式的设置方法。
/// </param>
public STBlinkPattern(string pattern, uint cycle = uint.MaxValue)
{
Debug.Assert(!string.IsNullOrEmpty(pattern), "pattern can not be null");
TotalCycles = cycle;
Pattern = pattern;
IsPlcMode = false;
}
/// <summary>
/// 创建信号灯塔元件闪烁模式对象的实例。
/// </summary>
/// <param name="cycle">总循环次数0或负值表示无限循环。</param>
/// <param name="frequencyHz">
/// PLC控制模式下的闪烁频率。
/// </param>
/// <param name="fallbackPattern">
/// 如果PLC不支持设置闪烁频率则回落到此模式。
/// </param>
public STBlinkPattern(float frequencyHz, uint cycle = uint.MaxValue, string fallbackPattern = "-----.....")
{
TotalCycles = cycle;
Pattern = fallbackPattern;
FrequencyHz = frequencyHz;
IsPlcMode = true;
}
#endregion
#region Properties
/// <summary>
/// 返回是否为PLC控制模式。
/// <br/>
/// <remarks>PLC模式指闪烁效果有PLC控制以提供更精确的控制效果。</remarks>
/// </summary>
public bool IsPlcMode { get; }
/// <summary>
/// 设置或返回总循环次数。
/// </summary>
[DataMember]
public uint TotalCycles { get; set; }
/// <summary>
/// 设置或返回闪烁模式。
/// <remarks>
/// 闪烁模式以字符串形式表达,表达式中仅允许包含字符’-‘(英文减号)和’.‘(英文句号)。
/// 其中<value>-</value>表示开100ms<value>.</value>表示关100ms。
/// <br/>
/// 通过'-'和‘.‘的组合,可描述不同的闪烁模式。
/// </remarks>
/// </summary>
[DataMember]
public string Pattern { get; set; }
/// <summary>
/// 闪烁频率。
/// </summary>
public float FrequencyHz { get; set; }
#endregion
#region Static Methods
/// <summary>
/// 解析闪烁模式字串生成闪烁数据供M<see cref="SignalTowerPartBase"/>产生闪烁效果。
/// </summary>
/// <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)
{
// var regex = new Regex(@"(([-\.])(\2*))");
reason = "";
blinkData = new List<BlinkDataType>();
// 校验Pattern字串的正则Pattern仅允许有字符-‘和’.’组成。
var regPatternFormat = new Regex(REG_PATT_BLINK_PATTERN);
// Pattern分组正则
var regGroup = new Regex(@"([\-\.])\1*");
if (!regPatternFormat.IsMatch(Pattern))
{
// 如果存在除-和.以外的字符则为非法Pattern字串。
reason = "pattern contains illegal characters";
LOG.Error(reason);
return false;
}
var matches = regGroup.Matches(Pattern);
foreach (Match match in matches)
{
if (match.Success && match.Groups.Count == 2)
{
var leadChar = match.Groups[1].Value; // 编组字符
var length = (uint)match.Length;
// 根据每组的字符判断动作。
TowerLightStatus action;
switch (leadChar)
{
case "-":
action = TowerLightStatus.On;
break;
case ".":
action = TowerLightStatus.Off;
break;
default:
LOG.Error($"Undefined character {leadChar} in pattern");
continue;
}
blinkData.Add(new(action, DELAY_MS_PER_CHAR * length));
}
}
return true;
}
/// <summary>
/// <inheritdoc cref="Object.ToString()"/>
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"IsPlcMode={IsPlcMode}, Freq={FrequencyHz}Hz, Pattern={Pattern}";
}
/// <summary>
/// 获取预设的快速闪烁模式。
/// </summary>
/// <remarks>
/// 开200ms关200ms无限循环。
/// </remarks>
/// <returns></returns>
public static STBlinkPattern GetFastBlinkPattern()
{
return new STBlinkPattern("-----.....");
}
/// <summary>
/// 获取预设的慢速闪烁模式。
/// </summary>
/// <remarks>
/// 开1s关1s无限循环。
/// </remarks>
/// <returns></returns>
public static STBlinkPattern GetSlowBlinkPattern()
{
return new STBlinkPattern("----------..........");
}
/// <summary>
/// 获取预设的工艺完成闪烁模式。
/// </summary>
/// <remarks>
/// 以开200ms、关200ms方式连续闪烁3次然后关1s循环5次。
/// </remarks>
/// <returns></returns>
public static STBlinkPattern GetProcessDoneBlinkPattern()
{
return new STBlinkPattern("--..--..--..........");
}
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
}