CommonWeighbridgeHandler.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package com.gzlh.device.weighbridge.handler.impl;
  2. import cn.hutool.core.thread.ThreadUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import cn.hutool.extra.spring.SpringUtil;
  5. import cn.hutool.json.JSONUtil;
  6. import cn.hutool.log.StaticLog;
  7. import com.gzlh.bus.ChannelCacheManager;
  8. import com.gzlh.bus.SysConfig;
  9. import com.gzlh.bus.EventDataManager;
  10. import com.gzlh.bus.EventBus;
  11. import com.gzlh.config.SystemObject;
  12. import com.gzlh.config.dto.SerialSetting;
  13. import com.gzlh.device.led.utils.LedOptions;
  14. import com.gzlh.device.weighbridge.event.WeighbridgeEvent;
  15. import com.gzlh.utils.DeviceCache;
  16. import lombok.extern.slf4j.Slf4j;
  17. import java.util.*;
  18. import java.util.concurrent.CopyOnWriteArrayList;
  19. import java.util.stream.Collectors;
  20. import java.util.stream.Stream;
  21. @Slf4j
  22. public class CommonWeighbridgeHandler {
  23. private final static List<Integer> WEIGHT_CACHE = new CopyOnWriteArrayList<>();
  24. public static boolean isStart = false;
  25. public static boolean hsCar = false;
  26. /**
  27. * 添加地磅数据到缓存
  28. *
  29. * @param weight 地磅数
  30. */
  31. public static void cacheWeight(int weight) {
  32. if (!isStart) {
  33. WEIGHT_CACHE.clear();
  34. return;
  35. }
  36. WEIGHT_CACHE.add(weight);
  37. }
  38. /**
  39. * 开始读取地磅数据
  40. */
  41. public static void startToRead() {
  42. //不启用
  43. if (!ChannelCacheManager.stateEnable(SysConfig.channelSetting.getChannelCode())) {
  44. return;
  45. }
  46. isStart = true;
  47. ThreadUtil.execute(new WatchThread());
  48. }
  49. /**
  50. * 监控地磅缓存是否读取到了数据
  51. * 监控2秒内的地磅数
  52. */
  53. static class WatchThread implements Runnable {
  54. private int time = 5000;
  55. @Override
  56. public void run() {
  57. int averaWeight = 0;
  58. SerialSetting serialSetting = SysConfig.serialSetting;
  59. while (time > 0) {
  60. if (!isStart) {
  61. return;
  62. }
  63. time = time - 1000;
  64. // 检查前后红外和雷达的触发情况
  65. // deviceStatus = new StringBuffer(DeviceCache.getPlcStatus()).reverse().toString();
  66. ThreadUtil.sleep(1000);
  67. }
  68. isStart = false;
  69. averaWeight = handlerWeight();
  70. log.info("----------weight---------:{}", averaWeight);
  71. EventDataManager.cacheData("weight", averaWeight);
  72. }
  73. private int handlerWeight() {
  74. List<Integer> list = WEIGHT_CACHE;
  75. log.info("w:{}", JSONUtil.toJsonStr(list));
  76. if (list.isEmpty()) {
  77. return 0;
  78. }
  79. int size = list.size();
  80. int index = (size * 3) / 4;
  81. return list.get(index);
  82. }
  83. public static int findClosestWithHighestFrequency(List<Integer> numbers) {
  84. if (numbers == null || numbers.size() == 0) {
  85. throw new IllegalArgumentException("数组不能为空");
  86. }
  87. // 计算平均值
  88. double sum = 0;
  89. for (int number : numbers) {
  90. sum += number;
  91. }
  92. double average = sum / numbers.size();
  93. // 使用Map存储每个数字的出现次数
  94. Map<Integer, Integer> frequencyMap = new HashMap<>();
  95. // 使用Map存储每个数字与平均值的误差
  96. Map<Integer, Double> differenceMap = new HashMap<>();
  97. // 计算每个数字的频率和误差
  98. for (int number : numbers) {
  99. frequencyMap.put(number, frequencyMap.getOrDefault(number, 0) + 1);
  100. differenceMap.put(number, Math.abs(number - average));
  101. }
  102. int result = numbers.get(0);
  103. double minDifference = Double.MAX_VALUE;
  104. int maxFrequency = 0;
  105. // 遍历所有不同的数字
  106. for (int number : frequencyMap.keySet()) {
  107. double currentDifference = differenceMap.get(number);
  108. int currentFrequency = frequencyMap.get(number);
  109. // 如果找到误差更小的数字
  110. if (currentDifference < minDifference) {
  111. minDifference = currentDifference;
  112. maxFrequency = currentFrequency;
  113. result = number;
  114. }
  115. // 如果误差相同,比较频率
  116. else if (currentDifference == minDifference && currentFrequency > maxFrequency) {
  117. maxFrequency = currentFrequency;
  118. result = number;
  119. }
  120. }
  121. return result;
  122. }
  123. }
  124. public static void main(String[] args) {
  125. String str = "51200,51180,51100,51160,51140,51160,51160";
  126. List<Integer> list = StrUtil.split(str, ",").stream().map(s -> Integer.parseInt(s)).collect(Collectors.toList());
  127. System.out.println(list.stream().collect(Collectors.averagingLong(Integer::intValue)));
  128. System.out.println(WatchThread.findClosestWithHighestFrequency(list));
  129. }
  130. }