QueryInTankStatusReportResponse.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using Edge.Core.IndustryStandardInterface.ATG;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Text;
  7. namespace VeederRoot_ATG_Console.MessageEntity.Incoming
  8. {
  9. /// <summary>
  10. /// i|I205, checking any active alarms from device.
  11. /// </summary>
  12. public class QueryInTankStatusReportResponse : IncomingMessageBase
  13. {
  14. public int? TankNumberInFunctionCode
  15. {
  16. get
  17. {
  18. if (base.FunctionCode.Item1 == MessageFormat.Display)
  19. return null;
  20. var r = int.Parse(base.FunctionCode.Item3);
  21. return r;
  22. }
  23. }
  24. public DateTime? CurrentDateAndTime
  25. {
  26. get
  27. {
  28. if (base.FunctionCode.Item1 == MessageFormat.Display)
  29. return null;
  30. return DateTime.ParseExact(
  31. Encoding.ASCII.GetString(base.DataFieldAndOptionalCheckSumAndETX.Take(10).ToArray()),
  32. "yyMMddHHmm", CultureInfo.InvariantCulture);
  33. }
  34. }
  35. /// <summary>
  36. /// Gets the all active OR unacknowledged alarms and warnings up to the limit of 25 alarms in display format,
  37. /// and 150 alarms in computer format.
  38. /// </summary>
  39. public List<TankAlarms> TanksOfAlarms
  40. {
  41. get
  42. {
  43. // skip 10 bytes of current date and time
  44. var rawDataBody = base.DataFieldAndOptionalCheckSumAndETX.Skip(10)
  45. //and exclude tail of -> && + 4 bytes check sum + ETX <- which is total 7 bytes.
  46. .Take(base.DataFieldAndOptionalCheckSumAndETX.Count - 10 - 7);
  47. /*
  48. * TT - Tank Number (Decimal, 00=all) - 2 bytes
  49. * nn - Number of alarms active for tank (Hex, 00=none) - 2 bytes
  50. *
  51. * ABOVE TOTAL LEN IS 4
  52. */
  53. var datas = new List<TankAlarms>();
  54. int previousTotalDataCount = 0;
  55. while (true)
  56. {
  57. var buffer = rawDataBody.Skip(previousTotalDataCount);
  58. var tankNumber = int.Parse(Encoding.ASCII.GetString(buffer.Take(2).ToArray()));
  59. var alarmBodyLen = int.Parse(Encoding.ASCII.GetString(buffer.Skip(2).Take(2).ToArray()));
  60. datas.Add(new TankAlarms(tankNumber,
  61. buffer.Skip(2 + 2).Take(alarmBodyLen * 2).ToArray()));
  62. previousTotalDataCount += 2 + 2 + alarmBodyLen * 2;
  63. if (previousTotalDataCount == rawDataBody.Count()) break;
  64. }
  65. return datas;
  66. }
  67. }
  68. public override string ToLogString()
  69. {
  70. return this.GetType().Name + " Current DateTime: " + this.CurrentDateAndTime.Value.ToString("yyyy-MM-dd HH:mm")
  71. + ", TankNumber_InFunctionCode: " + this.TankNumberInFunctionCode
  72. + ", data-> " + this.TanksOfAlarms.Select(d => d.ToFullLogString())
  73. .Aggregate((acc, n) => acc + " | " + n); ;
  74. }
  75. /// <summary>
  76. /// Gets the all active OR unacknowledged alarms and warnings up to the limit of 25 alarms in display format,
  77. /// and 150 alarms in computer format.
  78. /// </summary>
  79. public class TankAlarms
  80. {
  81. /// <summary>
  82. /// without length bytes header.
  83. /// so each 2 bytes constructs an alarm code.
  84. /// </summary>
  85. private byte[] alarmsBodyBytes;
  86. /// <summary>
  87. ///
  88. /// </summary>
  89. /// <param name="tankNumber"></param>
  90. /// <param name="alarmsBodyBytes">without length bytes header.</param>
  91. public TankAlarms(int tankNumber, byte[] alarmsBodyBytes)
  92. {
  93. this.TankNumber = tankNumber;
  94. this.alarmsBodyBytes = alarmsBodyBytes;
  95. }
  96. public int TankNumber { get; }
  97. public int NumberOfAlarmsActiveForThisTank
  98. {
  99. get
  100. {
  101. var nn = this.alarmsBodyBytes.Length / 2;
  102. return nn;
  103. }
  104. }
  105. public IEnumerable<AlarmType> Alarms
  106. {
  107. get
  108. {
  109. var result = new List<AlarmType>();
  110. for (int i = 0; i < this.alarmsBodyBytes.Length; i += 2)
  111. {
  112. var _ = Enum.Parse(typeof(AlarmType),
  113. Encoding.ASCII.GetString(new byte[] { this.alarmsBodyBytes[i], this.alarmsBodyBytes[i + 1] }));
  114. result.Add((AlarmType)_);
  115. }
  116. return result;
  117. }
  118. }
  119. public string ToFullLogString()
  120. {
  121. return "Tank with Number: " + this.TankNumber + " has "
  122. + this.NumberOfAlarmsActiveForThisTank + " AlarmsActive, "
  123. + "Active Alarms: "
  124. + (this.Alarms != null && this.Alarms.Any() ?
  125. this.Alarms.Select(a => a.ToString()).Aggregate((acc, n) => acc + "," + n)
  126. : "");
  127. }
  128. //public string ToSimpleLogString()
  129. //{
  130. // return "Tank with Number: " + (this.TankNumber ?? -1) + " has ProductCode: " + (this.ProductCode ?? ' ');
  131. //}
  132. }
  133. }
  134. }