ProtocolProxyBase.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel.DataAnnotations;
  5. using System.Linq;
  6. using System.Net.Sockets;
  7. using System.Reflection;
  8. using System.Runtime.InteropServices;
  9. using System.Text;
  10. using System.Threading.Channels;
  11. using System.Threading.Tasks;
  12. namespace WCS.Core
  13. {
  14. public abstract class ProtocolProxyBase : IProtocolProxy
  15. {
  16. string Id = Guid.NewGuid().ToString();
  17. public ProtocolInfo Info { get; private set; }
  18. public ushort BytesCount { get; private set; }
  19. Dictionary<string, PlcItem> Items = new Dictionary<string, PlcItem>();
  20. Type ProtocolType, ProtocolDataType;
  21. public Device Device { get; private set; }
  22. DataBlock Db;
  23. public ProtocolProxyBase(Device dev, ProtocolInfo info,Type protocolType,World world)
  24. {
  25. this.Device = dev;
  26. this.Info = info;
  27. Db = info.DBInfo.Ex(world);
  28. Db.DbChanged += Db_DbChanged;
  29. ProtocolType = protocolType;
  30. var bitStart = info.Position * 8;//偏移量,按位算
  31. //this.Start = start;
  32. //PlcDB db = new PlcDB(null, 50, 100);
  33. var lst = this.GetType().GetInterfaces().ToList();
  34. var ps = lst.SelectMany(v => v.GetProperties()).ToArray();
  35. foreach (var p in ps)
  36. {
  37. if (p.GetIndexParameters().Length > 0)
  38. continue;
  39. if (typeof(ProtocolProxyBase).GetProperty(p.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
  40. {
  41. continue;
  42. }
  43. #region 计算偏移量
  44. var modeNum = 0;
  45. var t = p.PropertyType;
  46. if (t.IsEnum)
  47. t = t.GetEnumUnderlyingType();
  48. if (t == typeof(bool))//bit类型,db块中无须补齐16位
  49. {
  50. modeNum = 1;
  51. }
  52. else if (t.IsPrimitive && Marshal.SizeOf(t) == 1)//byte char 等单字节类型,db块中无须补齐16位
  53. {
  54. modeNum = 8;
  55. }
  56. else//其他类型,db块中必须补齐16位
  57. {
  58. modeNum = 16;
  59. }
  60. var mod = bitStart % modeNum;
  61. if (mod > 0)
  62. {
  63. bitStart += modeNum - mod;
  64. }
  65. #endregion
  66. byte arrlen = 0;
  67. byte strLen = 0;
  68. if (t.IsArray)
  69. {
  70. var attr = p.GetCustomAttributes(typeof(MaxLengthAttribute), true).FirstOrDefault() as MaxLengthAttribute;
  71. if (attr != null)
  72. arrlen = (byte)attr.Length;
  73. }
  74. else if (p.PropertyType == typeof(string))
  75. {
  76. var attr = p.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
  77. strLen = (byte)attr.MaximumLength;
  78. }
  79. var m = typeof(DataBlock).GetMethod("Regist");
  80. m = m.MakeGenericMethod(p.PropertyType);
  81. var item = m.Invoke(Db, new object[] { this, Id, p.Name, bitStart, arrlen, strLen }) as PlcItem;
  82. Items.Add(p.Name, item);
  83. bitStart += item.DataSizeOfBits;
  84. BytesCount += item.DataSize;
  85. }
  86. //ProtocolDataType = ProtocolType.Assembly.GetTypes().Where(v => v.IsClass).Where(v => v.GetInterface(ProtocolType.Name) != null && v != this.GetType()).First();
  87. }
  88. byte[] Data = new byte[0];
  89. private void Db_DbChanged(byte[] data)
  90. {
  91. var pos = Info.Position - Db.Start;
  92. var bytes = data.Skip(pos).Take(BytesCount).ToArray();
  93. if (!Data.SequenceEqual(bytes))
  94. {
  95. Data = bytes;
  96. DataChanged();
  97. }
  98. }
  99. protected abstract void DataChanged();
  100. #region
  101. public void AddEvent(string eventName, Delegate delgate)
  102. {
  103. throw new NotImplementedException();
  104. }
  105. public void RemoveEvent(string eventName, Delegate delgate)
  106. {
  107. throw new NotImplementedException();
  108. }
  109. public T CallReturn<T>(string methodName, params object[] args)
  110. {
  111. throw new NotImplementedException();
  112. }
  113. public void CallVoid(string methodName, params object[] args)
  114. {
  115. throw new NotImplementedException();
  116. }
  117. public T Get<T>(string propertyName)
  118. {
  119. var item = Items[propertyName] as PlcItem<T>;
  120. var res = item.Value;
  121. var channel = Ltc.GetChannel();
  122. //Device.World.OnInternalLog(channel, $"获取{Device.Code}.{propertyName} 值:{res}");
  123. return res;
  124. }
  125. public void Set<T>(string propertyName, T value)
  126. {
  127. var item = Items[propertyName] as PlcItem<T>;
  128. item.Value = value;
  129. var channel = Ltc.GetChannel();
  130. //Device.World.OnInternalLog(channel, $"设置{Device.Code}.{propertyName} 值:{value}");
  131. }
  132. #endregion
  133. }
  134. }