PlcData.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using FreeRedis;
  2. using System.Collections.Generic;
  3. namespace Virtual_PLC
  4. {
  5. /// <summary>
  6. /// plc数据
  7. /// </summary>
  8. public class PlcData
  9. {
  10. private static RedisClient Redis { get; set; }
  11. /// <summary>
  12. /// 数据结构缓存
  13. /// </summary>
  14. private static List<PLCData> PLCDatas { get; set; } = new List<PLCData>();
  15. /// <summary>
  16. /// redis 链接字符串
  17. /// </summary>
  18. /// <param name="redisClient">Redis链接字符串</param>
  19. public PlcData(string redisClient)
  20. {
  21. Redis = new RedisClient(redisClient);
  22. }
  23. /// <summary>
  24. /// redis 链接字符串
  25. /// </summary>
  26. /// <param name="redisClient"></param>
  27. /// <returns></returns>
  28. public static PlcData Init(string redisClient)
  29. {
  30. return new PlcData(redisClient);
  31. }
  32. /// <summary>
  33. /// 初始化PLC数据
  34. /// </summary>
  35. /// <param name="pLCData">一个PLC</param>
  36. public void InitPlcData(PLCData pLCData)
  37. {
  38. if (!PLCDatas.Contains(pLCData))
  39. {
  40. PLCDatas.Add(pLCData);
  41. }
  42. //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
  43. var mun = pLCData.Length / pLCData.DataLength;
  44. int addstart = 0;
  45. for (int i = 0; i < mun; i++)
  46. {
  47. var key = $"{pLCData.IP}:{pLCData.DB}:{addstart}";
  48. if (Redis.Exists(key)) continue;
  49. Redis.Set(key, new byte[pLCData.DataLength]);
  50. addstart = addstart + pLCData.DataLength;
  51. }
  52. }
  53. /// <summary>
  54. /// 初始化PLC数据
  55. /// </summary>
  56. /// <param name="pLCDatas">多个PLC</param>
  57. public void InitPlcData(List<PLCData> pLCDatas)
  58. {
  59. pLCDatas.ForEach(v =>
  60. {
  61. InitPlcData(v);
  62. });
  63. }
  64. /// <summary>
  65. /// 按照DB读取
  66. /// </summary>
  67. /// <param name="pLCData"></param>
  68. /// <returns></returns>
  69. public static byte[] Read(PLCData pLCData)
  70. {
  71. byte[] data = new byte[pLCData.Length];
  72. //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
  73. var mun = pLCData.Length / pLCData.DataLength;
  74. int addstart = 0;
  75. for (int i = 0; i < mun; i++)
  76. {
  77. var a = Redis.Get<byte[]>($"{pLCData.IP}:{pLCData.DB}:{addstart}");
  78. a.CopyTo(data, addstart);
  79. addstart = addstart + pLCData.DataLength;
  80. }
  81. return data;
  82. }
  83. /// <summary>
  84. /// 按照长度读取
  85. /// </summary>
  86. /// <param name="pLCData"></param>
  87. /// <param name="startLength">起始长度</param>
  88. /// <returns></returns>
  89. public static byte[] Read(PLCData pLCData, int startLength)
  90. {
  91. return System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{startLength}"));
  92. }
  93. /// <summary>
  94. ///
  95. /// </summary>
  96. public static void Write(PLCData pLCData, int startLength, byte[] value)
  97. {
  98. var data = PLCDatas.Find(v => v.IP == pLCData.IP && v.DB == pLCData.DB);
  99. var start = startLength < data.DataLength ? 0 : (data.DataLength - startLength) + startLength;
  100. var bytes = System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{start}")); //获取原有数据
  101. value.CopyTo(bytes, startLength); //将变更的数据,更新到redis字节组中
  102. Redis.Set($"{pLCData.IP}:{pLCData.DB}:{start}", bytes);
  103. }
  104. }
  105. /// <summary>
  106. /// PLC数据结构
  107. /// </summary>
  108. public class PLCData
  109. {
  110. /// <summary>
  111. /// IP
  112. /// </summary>
  113. public string IP { get; set; }
  114. /// <summary>
  115. /// DB
  116. /// </summary>
  117. public int DB { get; set; }
  118. /// <summary>
  119. /// 总长度
  120. /// </summary>
  121. public int Length { get; set; }
  122. /// <summary>
  123. /// 数据长度
  124. /// </summary>
  125. public int DataLength { get; set; }
  126. }
  127. }