PlcCommunicationBase.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using HslCommunication.Core;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using TeamAAS.Communication.Interfaces;
  10. namespace TeamAAS.Communication.Base
  11. {
  12. public abstract class PlcCommunicationBase : BindableCommunicationBase
  13. {
  14. [Browsable(false)]
  15. public override string TypeKey => GetType().FullName;
  16. public abstract string PlcVendor { get; }
  17. [JsonIgnore, Browsable(false)]
  18. protected IReadWriteNet Driver;
  19. private byte _station = 1;
  20. [Category("II.PLC配置"), DisplayName("从站号"), Description("Modbus 等多从站协议用")]
  21. public byte Station
  22. {
  23. get => _station;
  24. set => SetProperty(ref _station, value);
  25. }
  26. private ByteOrderType _byteOrder = ByteOrderType.ABCD;
  27. [Category("II.PLC配置"), DisplayName("字节序"), Description("多字节数据字节排列顺序")]
  28. public ByteOrderType ByteOrder
  29. {
  30. get => _byteOrder;
  31. set => SetProperty(ref _byteOrder, value);
  32. }
  33. protected virtual string ResolveAddress(string address) => address;
  34. public override object ReadValue(string address) => ReadValue(address, DebugDataType.Int, 1);
  35. public override Task<object> ReadValueAsync(string address) => Task.Run(() => ReadValue(address));
  36. public override void WriteValue(string address, object value)
  37. {
  38. if (value == null) throw new ArgumentNullException(nameof(value));
  39. WriteValue(address, value, InferDataType(value), 1);
  40. }
  41. public override Task WriteValueAsync(string address, object value) => Task.Run(() => WriteValue(address, value));
  42. private static DebugDataType InferDataType(object value)
  43. {
  44. if (value is bool) return DebugDataType.Bool;
  45. if (value is byte) return DebugDataType.Byte;
  46. if (value is short) return DebugDataType.Short;
  47. if (value is ushort) return DebugDataType.Ushort;
  48. if (value is int) return DebugDataType.Int;
  49. if (value is uint) return DebugDataType.Uint;
  50. if (value is long) return DebugDataType.Long;
  51. if (value is ulong) return DebugDataType.Ulong;
  52. if (value is float) return DebugDataType.Float;
  53. if (value is double) return DebugDataType.Double;
  54. return DebugDataType.String;
  55. }
  56. public virtual object ReadValue(string address, DebugDataType type, ushort length = 1)
  57. {
  58. if (Driver == null) throw new InvalidOperationException($"{PlcVendor} 底层驱动未初始化,请先连接。");
  59. var addr = ResolveAddress(address);
  60. ushort len = Math.Max(length, (ushort)1);
  61. switch (type)
  62. {
  63. case DebugDataType.Bool:
  64. if (len == 1) { var r = Driver.ReadBool(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  65. { var r = Driver.ReadBool(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  66. case DebugDataType.Byte:
  67. { var r = Driver.Read(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  68. case DebugDataType.Short:
  69. if (len == 1) { var r = Driver.ReadInt16(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  70. { var r = Driver.ReadInt16(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  71. case DebugDataType.Ushort:
  72. if (len == 1) { var r = Driver.ReadUInt16(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  73. { var r = Driver.ReadUInt16(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  74. case DebugDataType.Int:
  75. if (len == 1) { var r = Driver.ReadInt32(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  76. { var r = Driver.ReadInt32(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  77. case DebugDataType.Uint:
  78. if (len == 1) { var r = Driver.ReadUInt32(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  79. { var r = Driver.ReadUInt32(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  80. case DebugDataType.Long:
  81. if (len == 1) { var r = Driver.ReadInt64(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  82. { var r = Driver.ReadInt64(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  83. case DebugDataType.Ulong:
  84. if (len == 1) { var r = Driver.ReadUInt64(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  85. { var r = Driver.ReadUInt64(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  86. case DebugDataType.Float:
  87. if (len == 1) { var r = Driver.ReadFloat(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  88. { var r = Driver.ReadFloat(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  89. case DebugDataType.Double:
  90. if (len == 1) { var r = Driver.ReadDouble(addr); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  91. { var r = Driver.ReadDouble(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  92. case DebugDataType.String:
  93. { var r = Driver.ReadString(addr, len); if (!r.IsSuccess) throw new InvalidOperationException(r.Message); return r.Content; }
  94. default:
  95. throw new ArgumentOutOfRangeException(nameof(type));
  96. }
  97. }
  98. public virtual void WriteValue(string address, object value, DebugDataType type, ushort length = 1)
  99. {
  100. if (Driver == null) throw new InvalidOperationException($"{PlcVendor} 底层驱动未初始化,请先连接。");
  101. var addr = ResolveAddress(address);
  102. HslCommunication.OperateResult result;
  103. switch (type)
  104. {
  105. case DebugDataType.Bool:
  106. result = value is bool[] bArr ? Driver.Write(addr, bArr) : Driver.Write(addr, Convert.ToBoolean(value));
  107. break;
  108. case DebugDataType.Byte:
  109. result = value is byte[] byArr ? Driver.Write(addr, byArr) : Driver.Write(addr, new[] { Convert.ToByte(value) });
  110. break;
  111. case DebugDataType.Short:
  112. result = value is short[] sArr ? Driver.Write(addr, sArr) : Driver.Write(addr, Convert.ToInt16(value));
  113. break;
  114. case DebugDataType.Ushort:
  115. result = value is ushort[] usArr ? Driver.Write(addr, usArr) : Driver.Write(addr, Convert.ToUInt16(value));
  116. break;
  117. case DebugDataType.Int:
  118. result = value is int[] iArr ? Driver.Write(addr, iArr) : Driver.Write(addr, Convert.ToInt32(value));
  119. break;
  120. case DebugDataType.Uint:
  121. result = value is uint[] uiArr ? Driver.Write(addr, uiArr) : Driver.Write(addr, Convert.ToUInt32(value));
  122. break;
  123. case DebugDataType.Long:
  124. result = value is long[] lArr ? Driver.Write(addr, lArr) : Driver.Write(addr, Convert.ToInt64(value));
  125. break;
  126. case DebugDataType.Ulong:
  127. result = value is ulong[] ulArr ? Driver.Write(addr, ulArr) : Driver.Write(addr, Convert.ToUInt64(value));
  128. break;
  129. case DebugDataType.Float:
  130. result = value is float[] fArr ? Driver.Write(addr, fArr) : Driver.Write(addr, Convert.ToSingle(value));
  131. break;
  132. case DebugDataType.Double:
  133. result = value is double[] dArr ? Driver.Write(addr, dArr) : Driver.Write(addr, Convert.ToDouble(value));
  134. break;
  135. case DebugDataType.String: result = Driver.Write(addr, value?.ToString() ?? ""); break;
  136. default: throw new ArgumentOutOfRangeException(nameof(type));
  137. }
  138. if (!result.IsSuccess) throw new InvalidOperationException(result.Message);
  139. }
  140. public Task<object> ReadValueAsync(string address, DebugDataType type, ushort length = 1)
  141. => Task.Run(() => ReadValue(address, type, length));
  142. public Task WriteValueAsync(string address, object value, DebugDataType type, ushort length = 1)
  143. => Task.Run(() => WriteValue(address, value, type, length));
  144. }
  145. }