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; namespace MECF.Framework.Common.Device.Bases; /// /// 信号灯塔元件闪烁模式。 /// [Serializable] [DataContract] public class STBlinkPattern { #region Variables /// /// 以-或.配置闪烁模式的字串正则表达式。 /// public const string REG_PATT_BLINK_PATTER = @"([^\-\.])+"; /// /// 模式字符串中每个字符对应的延时时长,单位毫秒。 /// private const uint DELAY_MS_PER_CHAR = 100; #endregion #region Constructors /// /// 构造信号灯元件闪烁模式。 /// 如果未指定闪烁模式,则默认开一秒,关一秒,无限循环。 /// public STBlinkPattern() { TotalCycles = 0; Pattern = "----------.........."; } /// /// 创建信号灯塔元件闪烁模式对象的实例。 /// /// 总循环次数,0或负值表示无限循环。 /// /// 闪烁模式。 /// 请参考属性以或许模式的设置方法。 /// public STBlinkPattern(string pattern, uint cycle = uint.MaxValue) { Debug.Assert(!string.IsNullOrEmpty(pattern), "pattern can not be null"); TotalCycles = cycle; Pattern = pattern; IsPlcMode = false; } /// /// 创建信号灯塔元件闪烁模式对象的实例。 /// /// 总循环次数,0或负值表示无限循环。 /// /// PLC控制模式下的闪烁频率。 /// /// /// 如果PLC不支持设置闪烁频率,则回落到此模式。 /// public STBlinkPattern(float frequencyHz, uint cycle = uint.MaxValue, string fallbackPattern = "-----.....") { TotalCycles = cycle; Pattern = fallbackPattern; FrequencyHz = frequencyHz; IsPlcMode = true; } #endregion #region Properties /// /// 返回是否为PLC控制模式。 ///
/// PLC模式指闪烁效果有PLC控制,以提供更精确的控制效果。 ///
public bool IsPlcMode { get; } /// /// 设置或返回总循环次数。 /// [DataMember] public uint TotalCycles { get; set; } /// /// 设置或返回闪烁模式。 /// /// 闪烁模式以字符串形式表达,表达式中仅允许包含字符’-‘(英文减号)和’.‘(英文句号)。 /// 其中-表示开100ms,.表示关100ms。 ///
/// 通过'-'和‘.‘的组合,可描述不同的闪烁模式。 ///
///
[DataMember] public string Pattern { get; set; } /// /// 闪烁频率。 /// public float FrequencyHz { get; set; } #endregion #region Static Methods /// /// 解析闪烁模式字串,生成闪烁数据供M产生闪烁效果。 /// /// 闪烁效果数据。 /// 解析失败原因。 /// /// True: 解析成功 /// False: 解析失败 /// public bool Parse(out List blinkData, out string reason) { // var regex = new Regex(@"(([-\.])(\2*))"); reason = ""; blinkData = new List(); // 校验Pattern字串的正则,Pattern仅允许有字符’-‘和’.’组成。 var regPatternFormat = new Regex(REG_PATT_BLINK_PATTER); // 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; } /// /// 获取预设的快速闪烁模式。 /// /// /// 开200ms,关200ms,无限循环。 /// /// public static STBlinkPattern GetFastBlinkPattern() { return new STBlinkPattern(0.5f, int.MaxValue, "--.."); } /// /// 获取预设的慢速闪烁模式。 /// /// /// 开1s,关1s,无限循环。 /// /// public static STBlinkPattern GetSlowBlinkPattern() { return new STBlinkPattern(1f, int.MaxValue, "----------.........." ); } /// /// 获取预设的工艺完成闪烁模式。 /// /// /// 以开200ms、关200ms方式连续闪烁3次,然后关1s,循环5次。 /// /// public static STBlinkPattern GetProcessDoneBlinkPattern() { return new STBlinkPattern(1f, 5, "--..--..--.........."); } public static STBlinkPattern ParseSTEvent(string pattern, uint cycle = int.MaxValue) { if (Regex.IsMatch(pattern, REG_PATT_BLINK_PATTER)) return new STBlinkPattern(pattern, cycle); if(float.TryParse(pattern, out var freq)) return new STBlinkPattern(freq, cycle); return GetFastBlinkPattern(); } #endregion }