ApiServiceImpl.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package com.jjt.biz.service.impl;
  2. import com.jjt.biz.domain.TwinDevice;
  3. import com.jjt.biz.service.IApiService;
  4. import com.jjt.biz.service.ITwinDeviceService;
  5. import com.jjt.biz.vo.*;
  6. import com.jjt.calc.domain.TwinCalcDay;
  7. import com.jjt.calc.service.ITwinCalcDayService;
  8. import com.jjt.calc.service.ITwinFormulaInfoService;
  9. import com.jjt.calc.service.ITwinPanHeadInfoService;
  10. import com.jjt.common.constant.CacheConstants;
  11. import com.jjt.common.core.redis.RedisCache;
  12. import com.jjt.utils.AsyncService;
  13. import com.jjt.utils.IotService;
  14. import com.jjt.utils.Tools;
  15. import com.jjt.ws.domain.TwinWorkshopCalc;
  16. import com.jjt.ws.service.ITwinWorkshopCalcService;
  17. import com.jjt.ws.service.ITwinWorkshopService;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.stereotype.Service;
  20. import javax.annotation.Resource;
  21. import java.math.BigDecimal;
  22. import java.math.RoundingMode;
  23. import java.time.LocalDate;
  24. import java.time.LocalDateTime;
  25. import java.time.ZoneOffset;
  26. import java.util.*;
  27. import java.util.concurrent.ExecutionException;
  28. import java.util.concurrent.Future;
  29. import java.util.stream.Collectors;
  30. /**
  31. * 首页统计数据
  32. *
  33. * @author wukai
  34. * @date 2024/5/4 20:35
  35. */
  36. @Service
  37. @Slf4j
  38. public class ApiServiceImpl implements IApiService {
  39. @Resource
  40. private ITwinCalcDayService twinCalcDayService;
  41. @Resource
  42. private ITwinPanHeadInfoService panHeadInfoService;
  43. @Resource
  44. private ITwinDeviceService deviceService;
  45. @Resource
  46. private IotService iotService;
  47. @Resource
  48. private AsyncService asyncService;
  49. @Resource
  50. private ITwinFormulaInfoService twinFormulaInfoService;
  51. @Resource
  52. private RedisCache redisCache;
  53. @Resource
  54. private ITwinWorkshopService workshopService;
  55. @Resource
  56. private ITwinWorkshopCalcService wsCalcService;
  57. /**
  58. * 首页统计数据
  59. */
  60. @Override
  61. public void today() {
  62. List<WeekData> weekDataList = new ArrayList<>();
  63. IndexData indexData = new IndexData();
  64. IndexEfficiency efficiency = new IndexEfficiency();
  65. TwinCalcDay calcDay = twinCalcDayService.today();
  66. /*
  67. 获取当天产量数据
  68. */
  69. efficiency.setAEfficiency(calcDay.getEfficiencyA().floatValue());
  70. efficiency.setBEfficiency(calcDay.getEfficiencyB().floatValue());
  71. efficiency.setTotalLength(calcDay.getLength().floatValue());
  72. efficiency.setALength(calcDay.getLengthA().floatValue());
  73. efficiency.setBLength(calcDay.getLengthB().floatValue());
  74. //界面上重新计算重量 2024-12-25 用总长度除以373
  75. BigDecimal tw = calcDay.getLength().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  76. BigDecimal aw = calcDay.getLengthA().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  77. BigDecimal bw = calcDay.getLengthB().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  78. efficiency.setTotalWeight(tw.floatValue());
  79. efficiency.setAWeight(aw.floatValue());
  80. efficiency.setBWeight(bw.floatValue());
  81. efficiency.setATime(calcDay.getOpenTimeA().divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP).floatValue());
  82. efficiency.setBTime(calcDay.getOpenTimeB().divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP).floatValue());
  83. //如果产量累计产量为0,则稼动和生产时间都为0
  84. if (efficiency.getALength() == 0f) {
  85. efficiency.setAEfficiency(0f);
  86. efficiency.setATime(0f);
  87. }
  88. //如果产量累计产量为0,则稼动和生产时间都为0
  89. if (efficiency.getBLength() == 0f) {
  90. efficiency.setBEfficiency(0f);
  91. efficiency.setBTime(0f);
  92. }
  93. indexData.setEfficiency(efficiency);
  94. //7点前是属于前一生产天,所以这里直接减7小时即可
  95. LocalDateTime ldt = LocalDateTime.now().minusHours(7);
  96. //获取前面7天的数据
  97. LocalDate localDate = ldt.toLocalDate().minusDays(7);
  98. // TwinWorkshop ws = workshopService.selectTwinWorkshopByWsCode("WS02-D");
  99. Date date = Date.from(localDate.atStartOfDay(ZoneOffset.of("+8")).toInstant());
  100. List<TwinWorkshopCalc> wsCalcList = wsCalcService.listByWsCodeDate("WS02-D", date);
  101. //按日期统计用量
  102. Map<Date, TwinWorkshopCalc> resultMap = wsCalcList.stream().collect(Collectors.toMap(TwinWorkshopCalc::getDataDate, obj -> obj));
  103. List<TwinCalcDay> list = twinCalcDayService.selectTwinCalcDayListByTime(date);
  104. Map<Date, List<TwinCalcDay>> dayGroup = list.stream().collect(Collectors.groupingBy(TwinCalcDay::getTime, LinkedHashMap::new, Collectors.toList()));
  105. for (Map.Entry<Date, List<TwinCalcDay>> entry : dayGroup.entrySet()) {
  106. TwinCalcDay day = new TwinCalcDay(entry.getKey());
  107. List<TwinCalcDay> days = entry.getValue();
  108. day.calcDays(days);
  109. WeekData weekData = new WeekData();
  110. weekData.convert(day);
  111. TwinWorkshopCalc ws = resultMap.get(entry.getKey());
  112. if (ws != null) {
  113. weekData.setAKwh(ws.getAValue());
  114. weekData.setBKwh(ws.getBValue());
  115. weekData.setKwh(ws.getTotalValue());
  116. } else {
  117. weekData.setAKwh(BigDecimal.ZERO);
  118. weekData.setBKwh(BigDecimal.ZERO);
  119. weekData.setKwh(BigDecimal.ZERO);
  120. }
  121. weekDataList.add(weekData);
  122. }
  123. indexData.setWeekData(weekDataList);
  124. IndexDevice device = new IndexDevice();
  125. device.setRunningRatio(calcDay.getRunningRatio());
  126. indexData.setDevice(device);
  127. redisCache.setCacheObject(CacheConstants.INDEX_CALC, indexData);
  128. }
  129. /**
  130. * 统计当前数据
  131. */
  132. @Override
  133. public void curr() {
  134. IndexData indexData = new IndexData();
  135. List<IndexAlarm> alarmList = new ArrayList<>();
  136. //配方统计数据
  137. List<FormulaTotal> formulaTotal = new ArrayList<>();
  138. //配方明细数据
  139. List<FormulaDetail> formulaDetail = new ArrayList<>();
  140. //送经量
  141. List<WarpRunIn> warpList = new ArrayList<>();
  142. //平方米克重统计数据
  143. List<GramMass> gramMasses = new ArrayList<>();
  144. //平方米克重明细数据
  145. List<GramMassDetail> gramMassDetails = new ArrayList<>();
  146. iotService.getToken();
  147. TwinDevice searchDevice = new TwinDevice();
  148. searchDevice.setOnline("1");
  149. List<TwinDevice> list = deviceService.selectTwinDeviceList(searchDevice);
  150. List<Future<Map<String, Object>>> futureList = new ArrayList<>();
  151. for (int i = 0; i < list.size(); i++) {
  152. TwinDevice twinDevice = list.get(i);
  153. futureList.add(asyncService.currData(twinDevice));
  154. }
  155. int stop1 = 0, stop2 = 0, stop6 = 0, stop8 = 0, onlineNum = 0, otherStop = 0, stopPan = 0;
  156. //停机明细
  157. List<StopDetailVO> stopList = new ArrayList<>();
  158. //所有设备当前数据
  159. Map<String, Map<String, Object>> currMap = new HashMap<>(16);
  160. try {
  161. for (Future<Map<String, Object>> future : futureList) {
  162. Map<String, Object> map = future.get();
  163. TwinDevice device = (TwinDevice) map.get("device");
  164. //判断是否小经编
  165. boolean isSmall = device.getDeviceCode().startsWith("C_");
  166. currMap.put(device.getDeviceCode(), map);
  167. StopDetailVO sdVO = new StopDetailVO();
  168. sdVO.setDeviceId(device.getDeviceId());
  169. sdVO.setDeviceName(device.getDeviceName());
  170. sdVO.setHasData(true);
  171. int total = (int) map.get("total");
  172. if (total == 0) {
  173. //可能会出现接口返回无数据的情况,需要设置设备状态为离线
  174. sdVO.setHasData(false);
  175. stopList.add(sdVO);
  176. otherStop++;
  177. continue;
  178. }
  179. float speed = (float) map.get("Capacity_data_1");
  180. int stopStatus = (int) map.get("Capacity_data_48");
  181. Object data4 = map.get("Capacity_data_4");
  182. if (device.getDeviceCode().startsWith("D_")) {
  183. speed = (float) map.get("Capacity_data_117");
  184. stopStatus = (int) map.get("Capacity_data_118");
  185. data4 = map.get("Capacity_data_110");
  186. }
  187. sdVO.setStop(stopStatus);
  188. sdVO.setSpeed(speed);
  189. stopList.add(sdVO);
  190. if (data4 instanceof Integer && (Integer) data4 == 0 || data4 instanceof Float && (Float) data4 == 0f) {
  191. //Capacity_data_4,如果设定落布米数为0,则证明当前数据无效
  192. //不能跟上面判断合并,不然报空指针
  193. continue;
  194. }
  195. //停机统计--start
  196. IndexAlarm stopCalc = new IndexAlarm();
  197. stopCalc.setCode(device.getDeviceCode());
  198. stopCalc.setName(device.getDeviceName());
  199. int alarmType = 0;
  200. if (speed > 0f || stopStatus == 0) {
  201. onlineNum++;
  202. } else {
  203. switch (stopStatus) {
  204. case 1:
  205. stop1++;
  206. alarmType = 10001;
  207. break;
  208. case 2:
  209. stop2++;
  210. alarmType = 10002;
  211. break;
  212. case 6:
  213. stop6++;
  214. alarmType = 10006;
  215. break;
  216. case 7:
  217. //7-盘头剩余圈数达到停机,表示停机叫料
  218. stop8++;
  219. alarmType = 10008;
  220. break;
  221. default:
  222. otherStop++;
  223. }
  224. }
  225. if (alarmType != 0) {
  226. stopCalc.setType(alarmType);
  227. alarmList.add(stopCalc);
  228. }
  229. //停机统计--end
  230. IndexPan pan = new IndexPan();
  231. pan.setCode(device.getDeviceCode());
  232. pan.setName(device.getDeviceName());
  233. //处理配方明细数据
  234. FormulaDetail detail = new FormulaDetail(isSmall, map);
  235. formulaDetail.add(detail);
  236. //处理平方米克重明细数据
  237. GramMassDetail gramMassDetail = new GramMassDetail(isSmall, map);
  238. gramMassDetails.add(gramMassDetail);
  239. //处理送经量数据
  240. WarpRunIn warpRunIn = new WarpRunIn(isSmall, map);
  241. warpList.add(warpRunIn);
  242. //盘头小于200圈的统计--start
  243. int len = 5;
  244. if (!isSmall) {
  245. len = 10;
  246. }
  247. boolean panFlag = false;
  248. for (int i = 0; i < len; i++) {
  249. int pos = 15 + i;
  250. int v = (int) map.get("Capacity_data_" + pos);
  251. if (v < 200) {
  252. //盘头小于200圈
  253. panFlag = true;
  254. break;
  255. }
  256. }
  257. if (panFlag) {
  258. stopPan++;
  259. }
  260. //盘头小于200圈的统计--end
  261. if (isSmall) {
  262. for (int i = 0; i < Tools.ALLOW_ALARM.length; i++) {
  263. //允许的告警编号
  264. boolean flag = (boolean) map.get("Alarm_unit_" + Tools.ALLOW_ALARM[i]);
  265. if (flag) {
  266. IndexAlarm indexAlarm = new IndexAlarm();
  267. indexAlarm.setCode(device.getDeviceCode());
  268. indexAlarm.setName(device.getDeviceName());
  269. indexAlarm.setType(i);
  270. alarmList.add(indexAlarm);
  271. }
  272. }
  273. }
  274. }
  275. } catch (InterruptedException | ExecutionException e) {
  276. throw new RuntimeException(e);
  277. }
  278. indexData.setAlarm(alarmList);
  279. IndexDevice device = new IndexDevice();
  280. device.setTotal(list.size());
  281. device.setOnline(onlineNum);
  282. device.setStop1(stop1);
  283. device.setStop2(stop2);
  284. device.setStop6(stop6);
  285. device.setStop8(stop8);
  286. device.setStopPan(stopPan);
  287. // 2024-11-18 告警数改为其他停机数
  288. // device.setAlarm(alarmList.size());
  289. device.setAlarm(otherStop);
  290. BigDecimal ratio = BigDecimal.valueOf(onlineNum * 100L).divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP);
  291. device.setRunningRatio(ratio.doubleValue());
  292. indexData.setDevice(device);
  293. Map<Float, Long> temp = formulaDetail.stream().collect(Collectors.groupingBy(FormulaDetail::getFormula_data_15, Collectors.counting()));
  294. for (Float v : temp.keySet()) {
  295. FormulaTotal total = new FormulaTotal();
  296. total.setHeight(v);
  297. int num = Math.toIntExact(temp.get(v));
  298. total.setNum(num);
  299. float percent = BigDecimal.valueOf(num).divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP).floatValue();
  300. total.setPercent(percent);
  301. formulaTotal.add(total);
  302. }
  303. temp = gramMassDetails.stream().collect(Collectors.groupingBy(GramMassDetail::getGramMass, Collectors.counting()));
  304. for (Float v : temp.keySet()) {
  305. GramMass total = new GramMass();
  306. total.setGramMass(v);
  307. int num = Math.toIntExact(temp.get(v));
  308. total.setNum(num);
  309. float percent = BigDecimal.valueOf(num).divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP).floatValue();
  310. total.setPercent(percent);
  311. gramMasses.add(total);
  312. }
  313. redisCache.setCacheObject(CacheConstants.DEVICE_CURRENT, currMap);
  314. redisCache.setCacheObject(CacheConstants.INDEX_ALARM, indexData);
  315. redisCache.setCacheObject(CacheConstants.INDEX_FORMULA_TOTAL, formulaTotal);
  316. redisCache.setCacheObject(CacheConstants.INDEX_FORMULA_DETAIL, formulaDetail);
  317. redisCache.setCacheObject(CacheConstants.INDEX_WARP_RUN_IN, warpList);
  318. redisCache.setCacheObject(CacheConstants.INDEX_GRAM_MASS, gramMasses);
  319. redisCache.setCacheObject(CacheConstants.INDEX_GRAM_MASS_DETAIL, gramMassDetails);
  320. redisCache.setCacheObject(CacheConstants.STOP_DETAIL, stopList);
  321. calcLength();
  322. }
  323. /**
  324. * 统计产量数据
  325. */
  326. private void calcLength() {
  327. IndexData indexData = redisCache.getCacheObject(CacheConstants.INDEX_CALC);
  328. IndexEfficiency efficiency = indexData.getEfficiency();
  329. TwinCalcDay calcDay = twinCalcDayService.calcLength();
  330. efficiency.setTotalLength(calcDay.getLength().floatValue());
  331. efficiency.setALength(calcDay.getLengthA().floatValue());
  332. efficiency.setBLength(calcDay.getLengthB().floatValue());
  333. //界面上重新计算重量 2024-12-25 用总长度除以373
  334. BigDecimal tw = calcDay.getLength().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  335. BigDecimal aw = calcDay.getLengthA().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  336. BigDecimal bw = calcDay.getLengthB().divide(BigDecimal.valueOf(373), 2, BigDecimal.ROUND_HALF_UP);
  337. efficiency.setTotalWeight(tw.floatValue());
  338. efficiency.setAWeight(aw.floatValue());
  339. efficiency.setBWeight(bw.floatValue());
  340. redisCache.setCacheObject(CacheConstants.INDEX_CALC, indexData);
  341. }
  342. }