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.

136 lines
5.8 KiB

8 months ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. namespace Mirle.Component.MPLC.MCProtocol
  6. {
  7. /// <summary>
  8. ///
  9. /// </summary>
  10. public class MCDevice
  11. {
  12. /// <summary>
  13. /// 建構式
  14. /// </summary>
  15. private MCDevice() { }
  16. /// <summary>
  17. /// 設備尋找表
  18. /// </summary>
  19. private static readonly Dictionary<string, Device> _DeviceLookup = new Dictionary<string, Device>()
  20. {
  21. ["SM"] = new Device(Device.TypeBit, "SM", 0x91, Device.AddressDecimal),
  22. ["SD"] = new Device(Device.TypeWord, "SD", 0xA9, Device.AddressDecimal),
  23. ["X"] = new Device(Device.TypeBit, "X*", 0x9C, Device.AddressHexadecimal),
  24. ["Y"] = new Device(Device.TypeBit, "Y*", 0x9D, Device.AddressHexadecimal),
  25. ["M"] = new Device(Device.TypeBit, "M*", 0x90, Device.AddressDecimal),
  26. ["L"] = new Device(Device.TypeBit, "L*", 0x92, Device.AddressDecimal),
  27. ["F"] = new Device(Device.TypeBit, "F*", 0x93, Device.AddressDecimal),
  28. ["V"] = new Device(Device.TypeBit, "V*", 0x94, Device.AddressDecimal),
  29. ["B"] = new Device(Device.TypeBit, "B*", 0xA0, Device.AddressHexadecimal),
  30. ["D"] = new Device(Device.TypeWord, "D*", 0xA8, Device.AddressDecimal),
  31. ["W"] = new Device(Device.TypeWord, "W*", 0xB4, Device.AddressHexadecimal),
  32. ["TS"] = new Device(Device.TypeBit, "TS", 0xC1, Device.AddressDecimal),
  33. ["TC"] = new Device(Device.TypeBit, "TC", 0xC0, Device.AddressDecimal),
  34. ["TN"] = new Device(Device.TypeWord, "TN", 0xC2, Device.AddressDecimal),
  35. ["SS"] = new Device(Device.TypeBit, "SS", 0xC7, Device.AddressDecimal),
  36. ["SC"] = new Device(Device.TypeBit, "SC", 0xC6, Device.AddressDecimal),
  37. ["SN"] = new Device(Device.TypeWord, "SN", 0xC8, Device.AddressDecimal),
  38. ["CS"] = new Device(Device.TypeBit, "CS", 0xC4, Device.AddressDecimal),
  39. ["CC"] = new Device(Device.TypeBit, "CC", 0xC3, Device.AddressDecimal),
  40. ["CN"] = new Device(Device.TypeWord, "CN", 0xC5, Device.AddressDecimal),
  41. ["SB"] = new Device(Device.TypeBit, "SB", 0xA1, Device.AddressHexadecimal),
  42. ["SW"] = new Device(Device.TypeWord, "SW", 0xB5, Device.AddressHexadecimal),
  43. ["S"] = new Device(Device.TypeBit, "S*", 0x98, Device.AddressDecimal),
  44. ["DX"] = new Device(Device.TypeBit, "DX", 0xA2, Device.AddressHexadecimal),
  45. ["DY"] = new Device(Device.TypeBit, "DY", 0xA3, Device.AddressHexadecimal),
  46. ["Z"] = new Device(Device.TypeWord, "Z*", 0xCC, Device.AddressDecimal),
  47. ["R"] = new Device(Device.TypeWord, "R*", 0xAF, Device.AddressDecimal),
  48. ["ZR"] = new Device(Device.TypeWord, "ZR", 0xB0, Device.AddressHexadecimal),
  49. };
  50. /// <summary>
  51. ///
  52. /// </summary>
  53. public string AsciiAddress { get; private set; }
  54. /// <summary>
  55. ///
  56. /// </summary>
  57. public string AsciiDeviceCode { get; private set; }
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. public byte BinaryDeviceCode { get; private set; }
  62. /// <summary>
  63. ///
  64. /// </summary>
  65. public int Address { get; private set; }
  66. /// <summary>
  67. ///
  68. /// </summary>
  69. public bool IsBit { get; private set; } = false;
  70. /// <summary>
  71. ///
  72. /// </summary>
  73. public bool IsWord => !IsBit;
  74. /// <summary>
  75. ///
  76. /// </summary>
  77. public int BitIndex { get; private set; }
  78. /// <summary>
  79. ///
  80. /// </summary>
  81. /// <param name="deviceAddress"></param>
  82. /// <returns></returns>
  83. public static MCDevice Parse(string deviceAddress)
  84. {
  85. return Parse(deviceAddress, 0);
  86. }
  87. /// <summary>
  88. ///
  89. /// </summary>
  90. /// <param name="deviceAddress"></param>
  91. /// <param name="offset"></param>
  92. /// <returns></returns>
  93. public static MCDevice Parse(string deviceAddress, int offset)
  94. {
  95. try
  96. {
  97. var item = _DeviceLookup.First(i => deviceAddress.StartsWith(i.Key));
  98. var device = item.Value;
  99. string asciiAddress = deviceAddress.TrimStart(item.Key.ToCharArray()).Split('.')[0];
  100. int bitIndex = deviceAddress.Contains(".") ? int.Parse(deviceAddress.Split('.')[1], System.Globalization.NumberStyles.HexNumber) : 0;
  101. if (device.DataType == Device.TypeBit)
  102. {
  103. bitIndex = 0;
  104. }
  105. int address = 0;
  106. switch (device.AddressType)
  107. {
  108. case Device.AddressHexadecimal:
  109. address = int.Parse(asciiAddress, System.Globalization.NumberStyles.HexNumber) + offset;
  110. asciiAddress = address.ToString("X");
  111. break;
  112. case Device.AddressDecimal:
  113. default:
  114. address = int.Parse(asciiAddress) + offset;
  115. asciiAddress = address.ToString("D");
  116. break;
  117. }
  118. return new MCDevice()
  119. {
  120. AsciiAddress = asciiAddress,
  121. AsciiDeviceCode = device.AsciiCode,
  122. BinaryDeviceCode = device.BinaryCode,
  123. Address = address,
  124. IsBit = device.DataType == Device.TypeBit,
  125. BitIndex = bitIndex,
  126. };
  127. }
  128. catch (Exception ex)
  129. {
  130. Debug.WriteLine($"{ex}");
  131. }
  132. return null;
  133. }
  134. }
  135. }