DataParser.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package com.zksy.infrared.utils;
  2. import com.zksy.common.utils.DecimalConversion;
  3. import com.zksy.infrared.domain.InfraredReadingMeter;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import java.math.BigDecimal;
  8. import java.math.BigInteger;
  9. import java.math.RoundingMode;
  10. import java.util.ArrayList;
  11. import java.util.Date;
  12. import java.util.List;
  13. @Slf4j
  14. public class DataParser {
  15. private static Logger logger = LoggerFactory.getLogger(DataParser.class);
  16. public static InfraredReadingMeter parseMessage(String msgString) {
  17. InfraredReadingMeter result = new InfraredReadingMeter();
  18. try {
  19. List<String> dataParts = new ArrayList<>();
  20. for (int i = 0; i < msgString.length(); i += 2) {
  21. int end = Math.min(i + 2, msgString.length());
  22. dataParts.add(msgString.substring(i, end));
  23. }
  24. // 检查数据部分是否足够
  25. if (dataParts.size() < 1 + 1 + 1 + 4) { // address(1) + function(1) + 跳过(1) + energy(4)
  26. logger.error("数据长度不足,无法解析: {}", msgString);
  27. return result;
  28. }
  29. String res1 = getStringList(dataParts, 1);
  30. result.setAddressCode(String.valueOf(Integer.parseInt(res1, 16)));
  31. String res2 = getStringList(dataParts, 1);
  32. result.setFunctionCode(String.valueOf(Integer.parseInt(res2, 16)));
  33. // 跳过一个部分
  34. getStringList(dataParts, 1);
  35. String res3 = getStringList(dataParts, 4);
  36. // 检查是否有null值
  37. if (res3.contains("null")) {
  38. logger.error("解析得到的电能数据包含无效值: {}", res3);
  39. return result;
  40. }
  41. BigInteger energyValue = new BigInteger(res3, 16);
  42. result.setElectricEnergy(energyValue.divide(BigInteger.valueOf(100)).doubleValue());
  43. result.setCreateTime(new Date());
  44. } catch (NumberFormatException e) {
  45. logger.error("解析数字时出错,输入字符串无效", e);
  46. } catch (Exception e) {
  47. logger.error("解析消息时出错", e);
  48. }
  49. return result;
  50. }
  51. public static String parseMeterNumber(String msgString) {
  52. try {
  53. // 检查字符串长度是否足够
  54. if (msgString.length() < 10) { // 6 + 4,确保有足够的长度
  55. logger.error("消息字符串太短,无法解析仪表编号: {}", msgString);
  56. return null;
  57. }
  58. String hexString = msgString.substring(6, msgString.length() - 4);
  59. // 转换为BigInteger并获取无符号十进制表示
  60. BigInteger bigInteger = new BigInteger(hexString, 16);
  61. return bigInteger.toString();
  62. } catch (Exception e) {
  63. logger.error("解析仪表编号时出错", e);
  64. return null;
  65. }
  66. }
  67. public static String shiftFromList(List<String> list) {
  68. if (list == null || list.isEmpty()) {
  69. logger.warn("尝试从空列表中获取元素");
  70. return null;
  71. }
  72. return list.remove(0);
  73. }
  74. private static String getStringList(List<String> dataParts, Integer q) {
  75. if (dataParts == null || dataParts.size() < q) {
  76. logger.warn("数据部分不足,需要{}个,实际只有{}个", q, dataParts == null ? 0 : dataParts.size());
  77. // 返回空字符串或处理不足的情况
  78. StringBuilder sb = new StringBuilder();
  79. for (int i = 0; i < q; i++) {
  80. sb.append(shiftFromList(dataParts));
  81. }
  82. return sb.toString();
  83. }
  84. StringBuilder res = new StringBuilder();
  85. for (int i = 0; i < q; i++) {
  86. String part = shiftFromList(dataParts);
  87. if (part == null) {
  88. logger.warn("获取第{}个元素时为null", i);
  89. }
  90. res.append(part);
  91. }
  92. return res.toString();
  93. }
  94. }