package com.fzzy.igds.utils; import com.alibaba.fastjson.JSONObject; import com.fzzy.igds.constant.Constant; import com.fzzy.igds.constant.DepotType; import com.fzzy.igds.data.GrainData; import com.fzzy.igds.data.GrainLay; import com.fzzy.igds.data.GrainPoint; import com.fzzy.igds.data.GrainRow; import com.fzzy.igds.domain.DepotConf; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.util.*; /** * @Description 粮情数据各个类型的转换控制 * @Author CZT * @Date 2025/12/9 10:19 */ @Slf4j public class GrainDataBuilder { /** * 根据单个粮情的数据信息,包括采集点和层信息 * * @param result * @param depotConf * @param depotType */ public static void updateGrainData(GrainData result, DepotConf depotConf, String depotType) { if (null == depotType || null == depotConf) { return; } List listPoints = new ArrayList<>(); List listLays = new ArrayList<>(); List listRows = new ArrayList<>(); // 根据仓库类型不同进行不同调整 if (DepotType.TYPE_02.getCode().equals(depotType)) {// 浅圆仓 result = buildLLaysAndRows2(listPoints, listLays, listRows, result, depotConf); } else if (DepotType.TYPE_03.getCode().equals(depotType)) { result = buildLLaysAndRows3(listPoints, listLays, listRows, result, depotConf); } else if (DepotType.TYPE_04.getCode().equals(depotType)) { result = buildLLaysAndRows2(listPoints, listLays, listRows, result, depotConf); } else { result = buildLLaysAndRows1(listPoints, listLays, listRows, result, depotConf); } result.setListLays(listLays); result.setListRows(listRows); result.setListPoints(listPoints); log.debug("---------{}", JSONObject.toJSONString(result)); } /** * 平方仓 跟新层数据和行数据 * * @param listPoints * @param listLays * @param listRows * @param result * @param depotConf * @return */ public static GrainData buildLLaysAndRows1(List listPoints, List listLays, List listRows, GrainData result, DepotConf depotConf) { String points = result.getPoints(); String cable = result.getCable(); // 获取布线规则 if (StringUtils.isEmpty(cable)) { return result; } if (StringUtils.isEmpty(points)) { return result; } String[] attr = cable.split("-"); int cableZ = Integer.valueOf(attr[0]); int cableY = Integer.valueOf(attr[1]); int cableX = Integer.valueOf(attr[2]); // 根据层更新层列表信息 updateListLays(listLays, cableX, cableY, cableZ); // 更新行数据的列表 updateListRows(listRows, cableX, cableY, cableZ); attr = points.split(","); GrainPoint point; Double tempT; GrainLay lay; GrainRow row; List listErrorTag = new ArrayList<>();// 故障或者错误的点 Double sumAll = 0.0; Double sumAllTemp = 0.0; int sumAllNum = 0; int tempT2; int x = 0, y = 0, z = 0, fz = 0; for (int i = 0; i < attr.length; i++) { z = i % cableZ; fz = z + 1; x = i / (cableZ * cableY); y = x * (cableZ * cableY); y = (i - y) / cableZ; // 倒转X轴 x = cableX - 1 - x; tempT = Double.valueOf(attr[i]); point = new GrainPoint(tempT, x, y, z, fz); // 统计每层数据 --初始化数据 lay = listLays.get(z); // 开始封装行数据信息 row = listRows.get(y); if (tempT <= Constant.ERROR_TEMP) { listErrorTag.add(i); lay.setSumNum(lay.getSumNum() - 1); row.setSumNum(row.getSumNum() - 1); if (x == (cableX - 1) || y == (cableY - 1) || x == 0 || y == 0) { lay.setSumOutNum(lay.getSumOutNum() - 1); } else { lay.setSumInNum(lay.getSumInNum() - 1); } } else { sumAllTemp += tempT; // 高温优化的启用要求1-处理单个高温点 if (null != depotConf && null != depotConf.getTempMax() && Constant.YN_Y.equals(depotConf.getGrainAuto())) { if (tempT > depotConf.getTempMax()) { tempT2 = (int) (tempT - depotConf.getTempMax()) + 1; tempT = NumberUtil.keepPrecision(tempT - tempT2, 1); result.setRemark("粮温检测正常"); log.debug("--原值={},--差值={},--结果={}", point.getTemp(), tempT2, tempT); } if (result.getTempMax() > depotConf.getTempMax()) { tempT2 = (int) (result.getTempMax() - depotConf .getTempMax()) + 1; result.setTempMax(NumberUtil.keepPrecision( result.getTempMax() - tempT2, 1)); } if (tempT > result.getTempMax()) { result.setTempMax(tempT); } } // 层行列补充 lay.setSumTemp(lay.getSumTemp() + tempT); lay.setSumTemp(NumberUtil.keepPrecision(lay.getSumTemp(), 1)); row.setSumTemp(row.getSumTemp() + tempT); row.setSumTemp(NumberUtil.keepPrecision(row.getSumTemp(), 1)); if (x == (cableX - 1) || y == (cableY - 1) || x == 0 || y == 0) { lay.setSumOutTemp(lay.getSumOutTemp() + tempT); } else { lay.setSumInTemp(lay.getSumInTemp() + tempT); } // 层最高最低 if (tempT > lay.getTempMax()) { lay.setTempMax(tempT); } if (tempT < lay.getTempMin()) { lay.setTempMin(tempT); } // 行最高最低 if (tempT > row.getTempMax()) { row.setTempMax(tempT); } if (tempT < row.getTempMin()) { row.setTempMin(tempT); } // log.info("----温度点={}",tempT); sumAll += tempT; sumAllNum = sumAllNum + 1; point.setTemp(tempT); } point.setTemp(NumberUtil.keepPrecision(point.getTemp(), 1)); listPoints.add(point); } // 调整层信息 for (GrainLay detail : listLays) { if (0 != detail.getSumNum()) { detail.setTempAve(detail.getSumTemp() / detail.getSumNum()); detail.setTempAve(NumberUtil.keepPrecision(detail.getTempAve(), 1)); } if (0 != detail.getSumInNum()) { detail.setTempAveIn(detail.getSumInTemp() / detail.getSumInNum()); detail.setTempAveIn(NumberUtil.keepPrecision( detail.getTempAveIn(), 1)); } if (0 != detail.getSumOutNum()) { detail.setTempAveOut(detail.getSumOutTemp() / detail.getSumOutNum()); detail.setTempAveOut(NumberUtil.keepPrecision( detail.getTempAveOut(), 1)); } //过滤掉比较的最大最小的值50和-50 if (detail.getTempMax() == -50) { detail.setTempMax(0.0); } if (detail.getTempMin() == 50) { detail.setTempMin(0.0); } } // 调整行信息 for (GrainRow detail : listRows) { if (0 != detail.getSumNum()) { detail.setTempAve(detail.getSumTemp() / detail.getSumNum()); detail.setTempAve(NumberUtil.keepPrecision(detail.getTempAve(), 1)); } //过滤掉比较的最大最小的值50和-50 if (detail.getTempMax() == -50) { detail.setTempMax(0.0); } if (detail.getTempMin() == 50) { detail.setTempMin(0.0); } } Random random = new Random(); Double randomValue; if (null != depotConf && Constant.YN_Y.equals(depotConf.getGrainAuto())) { if (listErrorTag.size() > 0) { for (Integer integer : listErrorTag) { point = listPoints.get(integer); // 获取当前层的信息 lay = listLays.get(point.getZ()); randomValue = lay.getTempMin() + (lay.getTempMax() - lay.getTempMin()) * random.nextDouble(); point.setTemp(NumberUtil.keepPrecision(randomValue, 1)); attr[integer] = NumberUtil.keepPrecision(randomValue, 1) + ""; listPoints.set(integer, point); } } } if (null != depotConf && Constant.YN_Y.equals(depotConf.getGrainAuto())) { { log.debug("---原平均={},后总温={},--后总个数={},后平均={},原总温={}", result.getTempAve(), sumAll, sumAllNum, sumAll / sumAllNum, sumAllTemp); result.setTempAve(NumberUtil.keepPrecision((sumAll / sumAllNum), 1)); } } result.setPoints(StringUtils.join(attr, ",")); return result; } /** * 圆筒仓 更新展示效果数据 * * @param listPoints * @param listLays * @param listRows * @param result * @param depotConf * @return */ private static GrainData buildLLaysAndRows2(List listPoints, List listLays, List listRows, GrainData result, DepotConf depotConf) { String points = result.getPoints(); String cableRule = result.getCable(); String cableCir = result.getCableCir(); if (StringUtils.isEmpty(points)) { return result; } // 获取布线规则 if (StringUtils.isEmpty(cableRule) || StringUtils.isEmpty(cableCir)) { return result; } // 每一圈列数 String[] cableRuleAtt = result.getCable().split("-"); // 每一圈层数 String[] cableCirAtt = result.getCableCir().split("-"); if (cableRuleAtt.length != cableCirAtt.length) { log.error("当前仓库:{},布线规则不正确,无法解析粮情信息……", depotConf.getDepotId()); return result; } // 获取最大的层配置--默认每一圈都一样 int layMax = Integer.valueOf(cableCirAtt[0]); for (int i = 0; i < cableCirAtt.length; i++) { if (Integer.valueOf(cableCirAtt[i]) >= layMax) layMax = Integer.valueOf(cableCirAtt[i]); } if (null == depotConf.getCableCone() || depotConf.getCableCone().isEmpty()) { depotConf.setCableCone(Constant.CABLE_CONE_0); } // 根据层更新层列表信息 updateListLaysCir(listLays, cableRuleAtt, cableCirAtt, layMax, depotConf.getCableCone()); String[] attr = points.split(","); GrainPoint point; Double tempT; GrainLay lay; int x = 0, y = 0, z = 1, fz = 0;// x=所在圈,从0开始;y代表电缆根号从0开始,z=代表所在层从1开始 List listErrorTag = new ArrayList<>();// 故障或者错误的点 List listHighTag = new ArrayList<>();// 高温点 int layNum = layMax;// 当前圈的层数 int rowNum = 1;// 当前圈的根数 int index = 0;// 当前温度点的位置 int startRow = 0;//当前粮情电缆根号 for (int i = 0; i < cableRuleAtt.length; i++) { x = i; rowNum = Integer.valueOf(cableRuleAtt[i]);// 根数 for (int k = 0; k < rowNum; k++) { y = k; for (int j = 0; j < layNum; j++) { z = j; fz = j + 1; tempT = Double.valueOf(attr[index]); index++; point = new GrainPoint(tempT, x, startRow, z, fz); // 统计每层数据 --初始化数据 lay = listLays.get(z); point.setTemp(tempT); listPoints.add(point); if (tempT <= Constant.ERROR_TEMP) { if (tempT != Constant.ADD_TEMP) { lay.setSumNum(lay.getSumNum() - 1); } } else { //判断是否高温优化 if (null != depotConf && null != depotConf.getTempMax() && Constant.YN_Y.equals(depotConf.getGrainAuto())) { if (tempT > depotConf.getTempMax()) { //记录高温点的位置 listHighTag.add(listPoints.size() - 1); } else { lay.setSumTemp(lay.getSumTemp() + tempT); // 层最高最低 if (tempT > lay.getTempMax()) { lay.setTempMax(tempT); } if (tempT < lay.getTempMin()) { lay.setTempMin(tempT); } } } else { lay.setSumTemp(lay.getSumTemp() + tempT); // 层最高最低 if (tempT > lay.getTempMax()) { lay.setTempMax(tempT); } if (tempT < lay.getTempMin()) { lay.setTempMin(tempT); } } } if (tempT == Constant.ERROR_TEMP || tempT == Constant.FAULT_TEMP) { listErrorTag.add(listPoints.size() - 1); } } startRow++; } } Double maxTemp = -50.0; //比较最高温 // 调整层信息 for (GrainLay detail : listLays) { if (0 != detail.getSumNum()) { detail.setTempAve(detail.getSumTemp() / detail.getSumNum()); detail.setTempAve(NumberUtil.keepPrecision(detail.getTempAve(), 1)); } if (0 != detail.getSumInNum()) { detail.setTempAveIn(detail.getSumInTemp() / detail.getSumInNum()); detail.setTempAveIn(NumberUtil.keepPrecision( detail.getTempAveIn(), 1)); } if (0 != detail.getSumOutNum()) { detail.setTempAveOut(detail.getSumOutTemp() / detail.getSumOutNum()); detail.setTempAveOut(NumberUtil.keepPrecision( detail.getTempAveOut(), 1)); } //过滤掉比较的最大最小的值50和-50 if (detail.getTempMax() == -50) { detail.setTempMax(0.0); } if (detail.getTempMin() == 50) { detail.setTempMin(0.0); } if (listHighTag.size() > 0) { if (detail.getTempMax() > maxTemp) { maxTemp = detail.getTempMax(); } } } Random random = new Random(); Double randomValue; //高温点替换为层平均值 if (null != depotConf && Constant.YN_Y.equals(depotConf.getGrainAuto())) { if (listHighTag.size() > 0) { for (Integer integer : listHighTag) { point = listPoints.get(integer); // 获取当前层的信息 lay = listLays.get(point.getZ()); randomValue = lay.getTempMin() + (lay.getTempMax() - lay.getTempMin()) * random.nextDouble(); point.setTemp(NumberUtil.keepPrecision(randomValue, 1)); attr[integer] = NumberUtil.keepPrecision(randomValue, 1) + ""; listPoints.set(integer, point); } //设置最高温 result.setTempMax(maxTemp); } } // 最后根据全局参数判断是否需要调整异常点数据进行调整 if (null != depotConf && Constant.YN_Y.equals(depotConf.getGrainAuto())) { if (listErrorTag.size() > 0) { for (Integer integer : listErrorTag) { point = listPoints.get(integer); // 获取当前层的信息 lay = listLays.get(point.getZ()); point.setTemp(lay.getTempAve()); listPoints.set(integer, point); } } } result.setListPoints(listPoints); result.setListLays(listLays); result.setPoints(StringUtils.join(attr, ",")); return result; } /** * 油筒仓解析,更新展示效果数据,解析方式同普通筒仓信息 * * @param listPoints * @param listLays * @param listRows * @param result * @param depotConf * @return */ private static GrainData buildLLaysAndRows3(List listPoints, List listLays, List listRows, GrainData result, DepotConf depotConf) { if (StringUtils.isEmpty(result.getOilHeight())) { result.setOilHeight("0.0-0.0"); log.warn("油桶仓={} 解析过程中没有获取到油面高度信息,默认显示为0", depotConf.getDepotId()); } else { if (result.getOilHeight().indexOf("-") == -1) { result.setOilHeight(result.getOilHeight() + "-" + result.getOilHeight()); log.warn("油桶仓={} 解析中没有获取建筑物的高度信息,默认建筑物高度等于液位高度", depotConf.getDepotId()); } } return buildLLaysAndRows2(listPoints, listLays, listRows, result, depotConf); } /** * @param listLays * @param cableX * @param cableY * @param cableZ */ private static void updateListLays(List listLays, int cableX, int cableY, int cableZ) {// 层从1开始 GrainLay lay; for (int i = 1; i <= cableZ; i++) { lay = new GrainLay(i, i - 1); lay.setSumNum(cableY * cableX); lay.setSumInNum((cableY - 2) * (cableX - 2)); lay.setSumOutNum(2 * cableY + 2 * cableX - 4); lay.setTempMin(50.0); lay.setTempMax(-50.0); listLays.add(lay); } } /** * @param listRows * @param cableX * @param cableY * @param cableZ */ private static void updateListRows(List listRows, int cableX, int cableY, int cableZ) {// 从0开始 GrainRow row; for (int i = 0; i < cableY; i++) { row = new GrainRow(i); row.setSumNum(cableZ * cableX); row.setTempMin(50.0); row.setTempMax(-50.0); listRows.add(row); } } /** * 圆筒仓--仓温度解析 * * @param listLays * @param cableRuleAtt * @param cableCirAtt * @param layMax * @param cableCone */ private static void updateListLaysCir(List listLays, String[] cableRuleAtt, String[] cableCirAtt, int layMax, String cableCone) { GrainLay lay; Map layMap = new HashMap<>(); for (int j = 0; j < cableRuleAtt.length; j++) { for (int i = 1; i <= layMax; i++) { if (layMap.containsKey(i + "")) { lay = layMap.get(i + ""); } else { lay = new GrainLay(i, i); } int sumNum = lay.getSumNum(); if (cableCone.equals(Constant.CABLE_CONE_2)) { if (Integer.parseInt(cableCirAtt[j]) >= i) { sumNum += Integer.parseInt(cableRuleAtt[j]); } } else { if (layMax - Integer.parseInt(cableCirAtt[j]) < i) { sumNum += Integer.parseInt(cableRuleAtt[j]); } } lay.setSumNum(sumNum); lay.setSumInNum(1); lay.setSumOutNum(1); lay.setTempMin(50.0); lay.setTempMax(-50.0); layMap.put(i + "", lay); } } for (int i = 1; i <= layMax; i++) { listLays.add(layMap.get(i + "")); } } /** * 圆筒仓--仓温度解析 * * @param listLays * @param cableRuleAtt * @param cableCirAtt * @param layMax */ private static void updateListLaysCir(List listLays, String[] cableRuleAtt, String[] cableCirAtt, int layMax) { GrainLay lay; for (int i = 1; i <= layMax; i++) { lay = new GrainLay(i, i); int sumNum = 0; for (int j = 0; j < cableRuleAtt.length; j++) { if (Integer.valueOf(cableCirAtt[j]) >= i) { sumNum += Integer.valueOf(cableRuleAtt[j]); } } lay.setSumNum(sumNum); lay.setSumInNum(1); lay.setSumOutNum(1); lay.setTempMin(50.0); lay.setTempMax(-50.0); listLays.add(lay); } } /** * 根据粮情温度,判断是否警告值,然后转换为页面需要渲染的值,主要备用和故障的值的调整 * * @param temp * @return */ public static String renderTempValue(Double temp) { if (temp > 45) return "故障"; if (temp == Constant.ERROR_TEMP) return "备用"; if (temp == Constant.FAULT_TEMP) return "故障"; if (temp == Constant.ADD_TEMP) return "--"; return temp + ""; } }