|
|
@ -4827,12 +4827,14 @@ public class QcServiceImpl implements QcService { |
|
|
// 无工单检验:先看302异常信号,1则读取异常数据并复位,0则直接返回空数据 |
|
|
// 无工单检验:先看302异常信号,1则读取异常数据并复位,0则直接返回空数据 |
|
|
logger.info("orderNo:{}",data.getOrderNo()); |
|
|
logger.info("orderNo:{}",data.getOrderNo()); |
|
|
if ("000#1".equals(data.getOrderNo())) { |
|
|
if ("000#1".equals(data.getOrderNo())) { |
|
|
Integer abnormalSignal = ModbusUtils.readSingleRegister(ip, port, unitId, isexceptionAdress); |
|
|
|
|
|
|
|
|
//logCollectorModelModbusProbe(ip, port, unitId, isexceptionAdress); |
|
|
|
|
|
Integer abnormalSignal = ModbusUtils.readSingleRegister(ip, port, unitId, isexceptionAdress-1); |
|
|
if (abnormalSignal == null || abnormalSignal == 0) { |
|
|
if (abnormalSignal == null || abnormalSignal == 0) { |
|
|
return new ArrayList<>(); |
|
|
return new ArrayList<>(); |
|
|
} |
|
|
} |
|
|
ArrayList<SubDetailValues> abnormalRows = getAbnormalCollectorData(ip, port, unitId, data); |
|
|
ArrayList<SubDetailValues> abnormalRows = getAbnormalCollectorData(ip, port, unitId, data); |
|
|
resetCollectorAbnormalRegisters(ip, port, unitId); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//resetCollectorAbnormalRegisters(ip, port, unitId); |
|
|
return abnormalRows; |
|
|
return abnormalRows; |
|
|
}else{ |
|
|
}else{ |
|
|
logger.info(port+","+ip+","+unitId+","+baseAddr+","+groups+","); |
|
|
logger.info(port+","+ip+","+unitId+","+baseAddr+","+groups+","); |
|
|
@ -4862,6 +4864,77 @@ public class QcServiceImpl implements QcService { |
|
|
return abnormalSignal != null && abnormalSignal == 1; |
|
|
return abnormalSignal != null && abnormalSignal == 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 无工单 000#1:屏显 40300/40302 等与 j2mod PDU(ref) 换算方式不一致时会导致“采集器型号”读错。 |
|
|
|
|
|
* 一次性读取窗口并打印多种常见换算,便于对照 Modbus 调试工具选用正确 ref。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void logCollectorModelModbusProbe(String ip, int port, int unitId, Integer dbExceptionAddr) { |
|
|
|
|
|
final int windowStart = 288; |
|
|
|
|
|
final int windowLen = 36; |
|
|
|
|
|
Map<Integer, Integer> raw = ModbusUtils.readHoldingRegisters(ip, port, unitId, windowStart, windowLen); |
|
|
|
|
|
logger.info("[采集器型号探测] ip={} port={} unitId={} DB异常寄存器ref(isexceptionAdress)={}", |
|
|
|
|
|
ip, port, unitId, dbExceptionAddr); |
|
|
|
|
|
if (raw == null || raw.isEmpty()) { |
|
|
|
|
|
logger.warn("[采集器型号探测] 批量读取 {}~{} 失败或无返回,后续单项读取仍可能成功", windowStart, windowStart + windowLen - 1); |
|
|
|
|
|
logSingleRegisterProbe(ip, port, unitId); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
|
for (int r = windowStart; r < windowStart + windowLen; r++) { |
|
|
|
|
|
Integer v = raw.get(r); |
|
|
|
|
|
sb.append(String.format(Locale.ROOT, "%d=%s ", r, v == null ? "null" : String.valueOf(v & 0xFFFF))); |
|
|
|
|
|
} |
|
|
|
|
|
logger.info("[采集器型号探测] pdu {}~{} (unsigned): {}", windowStart, windowStart + windowLen - 1, sb.toString().trim()); |
|
|
|
|
|
|
|
|
|
|
|
int v299 = regU(raw, 299); |
|
|
|
|
|
int v300 = regU(raw, 300); |
|
|
|
|
|
int v301 = regU(raw, 301); |
|
|
|
|
|
int v302 = regU(raw, 302); |
|
|
|
|
|
int v303 = regU(raw, 303); |
|
|
|
|
|
logger.info("[采集器型号探测] 常用单点: pdu299={} pdu300={} pdu301={} pdu302={} pdu303={}", |
|
|
|
|
|
v299, v300, v301, v302, v303); |
|
|
|
|
|
|
|
|
|
|
|
logger.info("[采集器型号探测] 换算A 屏显40300≈40001+299 → 看 pdu299={}; 屏显40302≈40001+301 → 看 pdu301={}", v299, v301); |
|
|
|
|
|
logger.info("[采集器型号探测] 换算B 屏显40300≈40000+300 → 看 pdu300={}; 屏显40302≈40000+302 → 看 pdu302={}", v300, v302); |
|
|
|
|
|
logger.info("[采集器型号探测] 换算C 后三位0300/0302 即 pdu300/pdu302 → {} / {}", v300, v302); |
|
|
|
|
|
|
|
|
|
|
|
Map<Integer, Integer> batch299 = ModbusUtils.readHoldingRegisters(ip, port, unitId, 299, 10); |
|
|
|
|
|
Map<Integer, Integer> batch300 = ModbusUtils.readHoldingRegisters(ip, port, unitId, 300, 10); |
|
|
|
|
|
logger.info("[采集器型号探测] FC03 连续10个自 pdu299: {}", formatRegisterBlock(batch299, 299, 10)); |
|
|
|
|
|
logger.info("[采集器型号探测] FC03 连续10个自 pdu300: {}", formatRegisterBlock(batch300, 300, 10)); |
|
|
|
|
|
|
|
|
|
|
|
Integer single300 = ModbusUtils.readSingleRegister(ip, port, unitId, 300); |
|
|
|
|
|
Integer single302 = ModbusUtils.readSingleRegister(ip, port, unitId, 302); |
|
|
|
|
|
Integer single301 = ModbusUtils.readSingleRegister(ip, port, unitId, 301); |
|
|
|
|
|
logger.info("[采集器型号探测] readSingleRegister 对照: ref301={} ref300={} ref302={}", single301, single300, single302); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 批量失败时再逐项单读,排除连接/批量限制问题 */ |
|
|
|
|
|
private static void logSingleRegisterProbe(String ip, int port, int unitId) { |
|
|
|
|
|
for (int ref : new int[]{297, 298, 299, 300, 301, 302, 303}) { |
|
|
|
|
|
Integer v = ModbusUtils.readSingleRegister(ip, port, unitId, ref); |
|
|
|
|
|
logger.info("[采集器型号探测] 单读 pdu{} → {}", ref, v); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static String formatRegisterBlock(Map<Integer, Integer> raw, int start, int count) { |
|
|
|
|
|
if (raw == null || raw.isEmpty()) { |
|
|
|
|
|
return "(empty)"; |
|
|
|
|
|
} |
|
|
|
|
|
StringBuilder b = new StringBuilder(); |
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
|
|
int r = start + i; |
|
|
|
|
|
Integer v = raw.get(r); |
|
|
|
|
|
b.append(String.format(Locale.ROOT, "[%d]=%s ", r, v == null ? "null" : String.valueOf(v & 0xFFFF))); |
|
|
|
|
|
} |
|
|
|
|
|
return b.toString().trim(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static int regU(Map<Integer, Integer> raw, int ref) { |
|
|
|
|
|
Integer v = raw.get(ref); |
|
|
|
|
|
return v == null ? -1 : (v & 0xFFFF); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private EquipmentFolderLocation getCollectorLocation(String site) { |
|
|
private EquipmentFolderLocation getCollectorLocation(String site) { |
|
|
LambdaQueryWrapper<EquipmentFolderLocation> wrapper = new LambdaQueryWrapper<>(); |
|
|
LambdaQueryWrapper<EquipmentFolderLocation> wrapper = new LambdaQueryWrapper<>(); |
|
|
wrapper.eq(EquipmentFolderLocation::getEquipmentNo, "J001"); |
|
|
wrapper.eq(EquipmentFolderLocation::getEquipmentNo, "J001"); |
|
|
@ -4872,8 +4945,8 @@ public class QcServiceImpl implements QcService { |
|
|
|
|
|
|
|
|
private ArrayList<SubDetailValues> getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception { |
|
|
private ArrayList<SubDetailValues> getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception { |
|
|
int readStartAddr = 400; |
|
|
int readStartAddr = 400; |
|
|
int readCount = 195; // 覆盖 400~594 |
|
|
|
|
|
Map<Integer, Integer> raw = ModbusUtils.readHoldingRegisters(ip, port, unitId, readStartAddr, readCount); |
|
|
|
|
|
|
|
|
int readCount = 195; // 覆盖 400~594(单次 FC03 字数不宜超过从站上限,需分批读) |
|
|
|
|
|
Map<Integer, Integer> raw = ModbusUtils.readHoldingRegistersBatched(ip, port, unitId, readStartAddr, readCount); |
|
|
ArrayList<SubDetailValues> subDetailValues = new ArrayList<>(); |
|
|
ArrayList<SubDetailValues> subDetailValues = new ArrayList<>(); |
|
|
if (raw == null || raw.isEmpty()) { |
|
|
if (raw == null || raw.isEmpty()) { |
|
|
return subDetailValues; |
|
|
return subDetailValues; |
|
|
@ -4911,26 +4984,27 @@ public class QcServiceImpl implements QcService { |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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(0))); |
|
|
|
|
|
detailValues.setSubDetailValueB(String.valueOf(abnormalValues.get(1))); |
|
|
|
|
|
detailValues.setSubDetailValueC(String.valueOf(abnormalValues.get(2))); |
|
|
|
|
|
detailValues.setSubDetailValueD(String.valueOf(abnormalValues.get(3))); |
|
|
|
|
|
detailValues.setSubDetailValueE(String.valueOf(abnormalValues.get(4))); |
|
|
|
|
|
detailValues.setSamplingLocation(String.format( |
|
|
|
|
|
"%d-%d-%d %d:%d:%d", |
|
|
|
|
|
|
|
|
// 每组 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(0), timeParts.get(1), timeParts.get(2), |
|
|
timeParts.get(3), timeParts.get(4), timeParts.get(5) |
|
|
|
|
|
)); |
|
|
|
|
|
subDetailValues.add(detailValues); |
|
|
|
|
|
|
|
|
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()); |
|
|
logger.info("解析后获取到的数据:{}",subDetailValues.toString()); |
|
|
|
|
|
batchInsertCollectorSubDetailRecords(data, subDetailValues); |
|
|
return subDetailValues; |
|
|
return subDetailValues; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -4953,13 +5027,50 @@ public class QcServiceImpl implements QcService { |
|
|
logger.info("复位结束"); |
|
|
logger.info("复位结束"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 按检验类型将采集子表明细批量写入对应 qc_*_sub_detail_record 表(常规 Modbus 与无工单异常采集共用)。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private void batchInsertCollectorSubDetailRecords(QcFAIRecordData data, ArrayList<SubDetailValues> 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<SubDetailValues> getCollectorDataByModbus(int port,String ip,int unitId,int baseAddr,int groups,QcFAIRecordData data) throws Exception { |
|
|
public ArrayList<SubDetailValues> getCollectorDataByModbus(int port,String ip,int unitId,int baseAddr,int groups,QcFAIRecordData data) throws Exception { |
|
|
final int avgAddr = 220; |
|
|
|
|
|
|
|
|
|
|
|
// 每个点占用 2 个寄存器,连续读取 200~221 共 22 个寄存器 |
|
|
|
|
|
final int quantity = (groups + 1) * 2; // 11 * 2 = 22 |
|
|
|
|
|
|
|
|
// 每个点占用 2 个寄存器;只读 groups 个测量点,不包含平均值(原 220 不再采集入库) |
|
|
|
|
|
final int quantity = groups * 2; |
|
|
|
|
|
|
|
|
//固定采集两次 |
|
|
|
|
|
|
|
|
// 固定采集两次:每次 groups 条,共 2 * groups 条(例如 10 通道时为 20 条) |
|
|
ArrayList<SubDetailValues> subDetailValues = new ArrayList<>(); |
|
|
ArrayList<SubDetailValues> subDetailValues = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4995,17 +5106,6 @@ public class QcServiceImpl implements QcService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 平均值地址 220,同样按照“高字在前”组合 |
|
|
|
|
|
int highRefAvg = avgAddr; |
|
|
|
|
|
int lowRefAvg = avgAddr + 1; |
|
|
|
|
|
Integer highAvg = raw.get(highRefAvg); |
|
|
|
|
|
Integer lowAvg = raw.get(lowRefAvg); |
|
|
|
|
|
if (lowAvg != null && highAvg != null) { |
|
|
|
|
|
int bits = (highAvg << 16) | (lowAvg & 0xFFFF); |
|
|
|
|
|
float f = Float.intBitsToFloat(bits); |
|
|
|
|
|
resultMap.put(String.valueOf(avgAddr), f); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, Float> entry : resultMap.entrySet()) { |
|
|
for (Map.Entry<String, Float> entry : resultMap.entrySet()) { |
|
|
SubDetailValues detailValues = new SubDetailValues(); |
|
|
SubDetailValues detailValues = new SubDetailValues(); |
|
|
detailValues.setBuNo(data.getBu()); |
|
|
detailValues.setBuNo(data.getBu()); |
|
|
@ -5021,35 +5121,7 @@ public class QcServiceImpl implements QcService { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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())); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
batchInsertCollectorSubDetailRecords(data, subDetailValues); |
|
|
return subDetailValues; |
|
|
return subDetailValues; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|