diff --git a/src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java b/src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java index 3f33f60b..b1c6727f 100644 --- a/src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java @@ -4943,7 +4943,7 @@ public class QcServiceImpl implements QcService { return equipmentFolderLocationService.getOne(wrapper); } - private ArrayList getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception { + /*private ArrayList getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception { int readStartAddr = 400; // 第 10 组第 5 路 float 占用 594~595,共需读到 595(含),即 400 起 196 个字 int readCount = 196; @@ -5027,6 +5027,248 @@ public class QcServiceImpl implements QcService { logger.info("复位结束"); } + private void batchInsertCollectorSubDetailRecords(QcFAIRecordData data, ArrayList subDetailValues) { + if (subDetailValues == null || subDetailValues.isEmpty()) { + return; + } + if ("ipqc".equals(data.getSopType())) { + StringBuilder sql = new StringBuilder(); + sql.append(" INSERT INTO qc_ipqc_sub_detail_record "); + sql.append(" (inspection_no, item_no, sub_detail_value, sampling_location, site, sampling_location_b, bu_no ,num) "); + sql.append(" VALUES "); + sql.append(" (:inspectionNo, :itemNo, :subDetailValue, :samplingLocation, :site, :samplingLocationB, :buNo ,:num) "); + parameterJdbcTemplate.batchUpdate(sql.toString(), SqlParameterSourceUtils.createBatch(subDetailValues.toArray())); + } else if ("iqc".equals(data.getSopType())) { + StringBuilder sql = new StringBuilder(); + sql.append(" INSERT INTO qc_iqc_sub_detail_record "); + sql.append(" (inspection_no, item_no, sub_detail_value, sampling_location, site, sampling_location_b, bu_no ,num) "); + sql.append(" VALUES "); + sql.append(" (:inspectionNo, :itemNo, :subDetailValue, :samplingLocation, :site, :samplingLocationB, :buNo ,:num) "); + parameterJdbcTemplate.batchUpdate(sql.toString(), SqlParameterSourceUtils.createBatch(subDetailValues.toArray())); + } else if ("fai".equals(data.getSopType())) { + StringBuilder sql = new StringBuilder(); + sql.append(" INSERT INTO qc_fai_sub_detail_record "); + sql.append(" (inspection_no, item_no, sub_detail_value, sampling_location, site, sampling_location_b, bu_no ,num) "); + sql.append(" VALUES "); + sql.append(" (:inspectionNo, :itemNo, :subDetailValue, :samplingLocation, :site, :samplingLocationB, :buNo ,:num) "); + parameterJdbcTemplate.batchUpdate(sql.toString(), SqlParameterSourceUtils.createBatch(subDetailValues.toArray())); + } else if ("fqc".equals(data.getSopType())) { + StringBuilder sql = new StringBuilder(); + sql.append(" INSERT INTO qc_fqc_sub_detail_record "); + sql.append(" (inspection_no, item_no, sub_detail_value, sampling_location, site, sampling_location_b, bu_no,num) "); + sql.append(" VALUES "); + sql.append(" (:inspectionNo, :itemNo, :subDetailValue, :samplingLocation, :site, :samplingLocationB, :buNo ,:num) "); + parameterJdbcTemplate.batchUpdate(sql.toString(), SqlParameterSourceUtils.createBatch(subDetailValues.toArray())); + } + } + + public ArrayList getCollectorDataByModbus(int port,String ip,int unitId,int baseAddr,int groups,QcFAIRecordData data) throws Exception { + + // 每个点占用 2 个寄存器;只读 groups 个测量点,不包含平均值(原 220 不再采集入库) + final int quantity = groups * 2; + + // 固定采集两次:每次 groups 条,共 2 * groups 条(例如 10 通道时为 20 条) + ArrayList subDetailValues = new ArrayList<>(); + + + for (int num = 0; num < 2; num++){ + Map resultMap = new HashMap<>(); + Map raw = null; + // 简单重试两次,尽量避免瞬时网络抖动导致读取失败 + for (int attempt = 0; attempt < 2; attempt++) { + raw = ModbusUtils.readHoldingRegisters(ip, port, unitId, baseAddr, quantity); + log.info("Modbus 采集成功 {}", raw); + if (raw != null && !raw.isEmpty()) { + break; + } + Thread.sleep(200); + } + + if (raw == null || raw.isEmpty()) { + log.warn("Modbus 采集失败 - IP: {}, Port: {}, unitId: {}, offset: {}, quantity: {}", ip, port, unitId, baseAddr, quantity); + return subDetailValues; + } + + // 设备实际为“高字在前”,即寄存器 addr 存高 16 位,addr+1 存低 16 位 + for (int i = 0; i < groups; i++) { + int addr = baseAddr + (i * 2); // 200, 202, ..., 218 + int highRef = addr; // 高字 + int lowRef = addr + 1; // 低字 + Integer high = raw.get(highRef); + Integer low = raw.get(lowRef); + if (low != null && high != null) { + resultMap.put(String.valueOf(addr), ModbusUtils.registersToFloatHighWordFirst(high, low)); + } + } + + for (Map.Entry entry : resultMap.entrySet()) { + SubDetailValues detailValues = new SubDetailValues(); + detailValues.setBuNo(data.getBu()); + detailValues.setInspectionNo(data.getInspectionNo()); + detailValues.setItemNo(data.getItemNo()); + detailValues.setSubDetailValue(entry.getValue().toString()); + detailValues.setIsSubmit("N"); + detailValues.setSite(data.getSite()); + detailValues.setNum(1); + subDetailValues.add(detailValues); + } + Thread.sleep(1001); + + } + + batchInsertCollectorSubDetailRecords(data, subDetailValues); + return subDetailValues; + } + + public Map getCollectorDataByModbus(String ip, int unitId) throws Exception { + int port = 502; + if(StringUtils.isBlank(ip)){ + ip = "172.26.58.213"; + } + unitId = 1; + // 10 组数据起始地址和平均值地址 + final int baseAddr = 200; + final int groups = 10; + final int avgAddr = 220; + + // 每个点占用 2 个寄存器,连续读取 200~221 共 22 个寄存器 + final int quantity = (groups + 1) * 2; // 11 * 2 = 22 + + Map resultMap = new HashMap<>(); + + // 启动地址 229、300(单寄存器),直接按 0-based ref 读取 + Integer start229 = ModbusUtils.readSingleRegister(ip, port, unitId, 229); + if (start229 != null) { + resultMap.put("229", start229.floatValue()); + } + Integer start300 = ModbusUtils.readSingleRegister(ip, port, unitId, 300); + if (start300 != null) { + resultMap.put("300", start300.floatValue()); + } + + Map raw = null; + // 简单重试两次,尽量避免瞬时网络抖动导致读取失败 + for (int attempt = 0; attempt < 2; attempt++) { + raw = ModbusUtils.readHoldingRegisters(ip, port, unitId, baseAddr, quantity); + if (raw != null && !raw.isEmpty()) { + break; + } + Thread.sleep(200); + } + + if (raw == null || raw.isEmpty()) { + log.warn("Modbus 采集失败 - IP: {}, Port: {}, unitId: {}, offset: {}, quantity: {}", ip, port, unitId, baseAddr, quantity); + return resultMap; + } + + // 10 组数据:200,202,...,218 + for (int i = 0; i < groups; i++) { + int addr = baseAddr + (i * 2); // 200, 202, ..., 218 + int lowRef = addr; // 低字 + int highRef = addr + 1; // 高字 + Integer low = raw.get(lowRef); + Integer high = raw.get(highRef); + if (low != null && high != null) { + resultMap.put(String.valueOf(addr), ModbusUtils.registersToFloatLowWordFirst(low, high)); + } + } + + // 平均值地址 220 + int lowRefAvg = avgAddr; + int highRefAvg = avgAddr + 1; + Integer lowAvg = raw.get(lowRefAvg); + Integer highAvg = raw.get(highRefAvg); + if (lowAvg != null && highAvg != null) { + resultMap.put(String.valueOf(avgAddr), ModbusUtils.registersToFloatLowWordFirst(lowAvg, highAvg)); + } + + return resultMap; + } +}*/ + private ArrayList getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception { + int readStartAddr = 400; + int readCount = 195; // 覆盖 400~594(单次 FC03 字数不宜超过从站上限,需分批读) + Map raw = ModbusUtils.readHoldingRegistersBatched(ip, port, unitId, readStartAddr, readCount); + ArrayList subDetailValues = new ArrayList<>(); + if (raw == null || raw.isEmpty()) { + return subDetailValues; + } + + for (int groupIdx = 0; groupIdx < 10; groupIdx++) { + int timeStartAddr = 400 + (groupIdx * 20); + int abnormalStartAddr = 406 + (groupIdx * 20); + + // 时间段地址按16位整型读取:每组 6 个寄存器(400~405、420~425...) + List timeParts = new ArrayList<>(); + for (int i = 0; i < 6; i++) { + Integer timeValue = raw.get(timeStartAddr + i); + timeParts.add(timeValue == null ? 0 : (timeValue & 0xFFFF)); + } + + // 异常数据地址按32位float读取(高字在前):406/408/410/412/414 ... + List abnormalValues = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + int highRef = abnormalStartAddr + (i * 2); + int lowRef = highRef + 1; + Integer high = raw.get(highRef); + Integer low = raw.get(lowRef); + if (high != null && low != null) { + int bits = (high << 16) | (low & 0xFFFF); + abnormalValues.add(Float.intBitsToFloat(bits)); + } else { + abnormalValues.add(0F); + } + } + logger.info("获取到的数据:{},时间:{}",abnormalValues.toString(),timeParts.toString()); + + boolean hasAbnormal = abnormalValues.stream().anyMatch(v -> v != 0F); + if (!hasAbnormal) { + continue; + } + + // 每组 1 套时间(6 个寄存器)对应 5 个异常通道:拆成 5 条记录,每条 1 数值 + 1 时间 + String collectedTime = String.format(Locale.ROOT, + "%d-%d %d:%d:%d", + timeParts.get(0), timeParts.get(1), timeParts.get(2), + timeParts.get(3), timeParts.get(4)); + for (int i = 0; i < 5; i++) { + SubDetailValues detailValues = new SubDetailValues(); + detailValues.setBuNo(data.getBu()); + detailValues.setInspectionNo(data.getInspectionNo()); + detailValues.setItemNo(data.getItemNo()); + detailValues.setIsSubmit("N"); + detailValues.setSite(data.getSite()); + detailValues.setNum(1); + detailValues.setSubDetailValue(String.valueOf(abnormalValues.get(i))); + detailValues.setSubDetailValueB(collectedTime); + detailValues.setSamplingLocationB(collectedTime); + subDetailValues.add(detailValues); + } + } + logger.info("解析后获取到的数据:{}",subDetailValues.toString()); + batchInsertCollectorSubDetailRecords(data, subDetailValues); + return subDetailValues; + } + + private void resetCollectorAbnormalRegisters(String ip, int port, int unitId) { + List resetAddrs = new ArrayList<>(Arrays.asList( + 302, + 406, 408, 410, 412, 414, + 426, 428, 430, 432, 434, + 446, 448, 450, 452, 454, + 466, 468, 470, 472, 474, + 486, 488, 490, 492, 494, + 506, 508, 510, 512, 514, + 526, 528, 530, 532, 534, + 546, 548, 550, 552, 554, + 566, 568, 570, 572, 574, + 586, 588, 590, 592, 594 + )); + logger.info("开始复位"); + ModbusUtils.resetRegisters(ip, port, unitId, resetAddrs); + logger.info("复位结束"); + } + /** * 按检验类型将采集子表明细批量写入对应 qc_*_sub_detail_record 表(常规 Modbus 与无工单异常采集共用)。 */ @@ -5100,7 +5342,9 @@ public class QcServiceImpl implements QcService { Integer high = raw.get(highRef); Integer low = raw.get(lowRef); if (low != null && high != null) { - resultMap.put(String.valueOf(addr), ModbusUtils.registersToFloatHighWordFirst(high, low)); + int bits = (high << 16) | (low & 0xFFFF); + float f = Float.intBitsToFloat(bits); + resultMap.put(String.valueOf(addr), f); } } @@ -5189,7 +5433,9 @@ public class QcServiceImpl implements QcService { Integer low = raw.get(lowRef); Integer high = raw.get(highRef); if (low != null && high != null) { - resultMap.put(String.valueOf(addr), ModbusUtils.registersToFloatLowWordFirst(low, high)); + int bits = (high << 16) | (low & 0xFFFF); + float f = Float.intBitsToFloat(bits); + resultMap.put(String.valueOf(addr), f); } } @@ -5199,7 +5445,9 @@ public class QcServiceImpl implements QcService { Integer lowAvg = raw.get(lowRefAvg); Integer highAvg = raw.get(highRefAvg); if (lowAvg != null && highAvg != null) { - resultMap.put(String.valueOf(avgAddr), ModbusUtils.registersToFloatLowWordFirst(lowAvg, highAvg)); + int bits = (highAvg << 16) | (lowAvg & 0xFFFF); + float f = Float.intBitsToFloat(bits); + resultMap.put(String.valueOf(avgAddr), f); } return resultMap;