You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.3 KiB

8 months ago
  1. using Mirle.Component.MPLC.DataBlocks.DeviceRange.Interfaces;
  2. using System;
  3. using System.Diagnostics;
  4. using System.Globalization;
  5. namespace Mirle.Component.MPLC.DataBlocks.DeviceRange
  6. {
  7. /// <summary>
  8. /// D 設備範圍
  9. /// </summary>
  10. public class DDeviceRange : ITypeDeviceRange
  11. {
  12. /// <summary>
  13. /// 建構式
  14. /// </summary>
  15. /// <param name="startAddress">起始位置</param>
  16. /// <param name="endAddress">結束位置</param>
  17. /// <exception cref="ArgumentException"></exception>
  18. public DDeviceRange(string startAddress, string endAddress)
  19. {
  20. StartAddress = startAddress;
  21. EndAddress = endAddress;
  22. if (!startAddress.StartsWith(_type) || !endAddress.StartsWith(_type))
  23. throw new ArgumentException("Wrong Type!!");
  24. try
  25. {
  26. _startOffset = int.Parse(startAddress[1..]);
  27. _endOffset = int.Parse(endAddress[1..]);
  28. }
  29. catch (Exception ex)
  30. {
  31. Debug.WriteLine($"{ex}");
  32. throw new ArgumentException("Wrong Address!!");
  33. }
  34. if (_startOffset > _endOffset)
  35. throw new ArgumentException("Wrong Address Range!!");
  36. WordLength = _endOffset - _startOffset + 1;
  37. }
  38. /// <summary>
  39. /// 設備類別
  40. /// </summary>
  41. private const string _type = nameof(DeviceType.D);
  42. /// <summary>
  43. /// 起始偏移量
  44. /// </summary>
  45. private readonly int _startOffset;
  46. /// <summary>
  47. /// 結束偏移量
  48. /// </summary>
  49. private readonly int _endOffset;
  50. /// <summary>
  51. /// 起始位置
  52. /// </summary>
  53. public string StartAddress { get; }
  54. /// <summary>
  55. /// 結束位置
  56. /// </summary>
  57. public string EndAddress { get; }
  58. /// <summary>
  59. /// 字元長度
  60. /// </summary>
  61. public int WordLength { get; }
  62. /// <summary>
  63. /// 位元組陣列長度
  64. /// </summary>
  65. /// <value>WordLength * 2</value>
  66. public int ByteArrayLength => WordLength * 2;
  67. /// <summary>
  68. /// 是否為同樣設備範圍
  69. /// </summary>
  70. /// <param name="address">位置</param>
  71. /// <returns>True/False</returns>
  72. public bool IsSameRange(string address)
  73. {
  74. return TryGetIndex(address, out _);
  75. }
  76. /// <summary>
  77. /// 是否為同樣設備類別
  78. /// </summary>
  79. /// <param name="address">位置</param>
  80. /// <returns>True/False</returns>
  81. private static bool IsSameType(string address)
  82. {
  83. return address.ToUpper().StartsWith(_type);
  84. }
  85. /// <summary>
  86. /// 取得索引
  87. /// </summary>
  88. /// <param name="address">位置</param>
  89. /// <param name="index">索引</param>
  90. /// <returns>True/False</returns>
  91. public bool TryGetIndex(string address, out int index)
  92. {
  93. if (!IsSameType(address))
  94. {
  95. index = -1;
  96. return false;
  97. }
  98. address = address[1..];
  99. address = address.Split('.')[0];
  100. index = int.Parse(address);
  101. if (index >= _startOffset && index <= _endOffset)
  102. return true;
  103. index = -1;
  104. return false;
  105. }
  106. /// <summary>
  107. /// 取得偏移量
  108. /// </summary>
  109. /// <param name="address">起始位置</param>
  110. /// <param name="offset">偏移量</param>
  111. /// <returns>True/False</returns>
  112. public bool TryGetOffset(string address, out int offset)
  113. {
  114. if (TryGetIndex(address, out int index))
  115. {
  116. offset = index - _startOffset;
  117. return true;
  118. }
  119. offset = -1;
  120. return false;
  121. }
  122. /// <summary>
  123. /// 取得位元組陣列偏移量
  124. /// </summary>
  125. /// <param name="address">位元組</param>
  126. /// <param name="offset">偏移量</param>
  127. /// <returns>True/False</returns>
  128. public bool TryGetByteArrayOffset(string address, out int offset)
  129. {
  130. if (TryGetIndex(address, out int index))
  131. {
  132. offset = (index - _startOffset) * 2;
  133. return true;
  134. }
  135. offset = -1;
  136. return false;
  137. }
  138. /// <summary>
  139. /// 取得位元組陣列位元索引
  140. /// </summary>
  141. /// <param name="address">位置</param>
  142. /// <param name="index">索引</param>
  143. /// <returns>True/False</returns>
  144. public bool TryGetByteArrayBitIndex(string address, out int index)
  145. {
  146. index = 0;
  147. try
  148. {
  149. if (address.Contains(".") && int.TryParse(address.Split('.')[1], NumberStyles.HexNumber, null, out index))
  150. {
  151. if (index >= 0 && index < 16)
  152. return true;
  153. index = 0;
  154. }
  155. return false;
  156. }
  157. catch (Exception ex)
  158. {
  159. Debug.WriteLine($"{ex}");
  160. }
  161. return false;
  162. }
  163. }
  164. }