Browse Source

胶水采集17.几数据

master
shenzhouyu 4 weeks ago
parent
commit
c8e4c68985
  1. 35
      src/main/java/com/xujie/sys/common/utils/ModbusUtils.java
  2. 74
      src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java

35
src/main/java/com/xujie/sys/common/utils/ModbusUtils.java

@ -8,6 +8,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
@ -15,7 +16,7 @@ public class ModbusUtils {
private static final Logger log = LoggerFactory.getLogger(ModbusUtils.class);
/** Modbus TCP 套接字超时(毫秒),用于建连与读写;弱网或从站响应慢时可适当加大 */
private static final int MODBUS_TCP_TIMEOUT_MS = 20000;
private static final int MODBUS_TCP_TIMEOUT_MS = 30000;
/**
* {@code ModbusCommunicateServiceImpl#getResponseMessage} 一致首寄存器为高 16 次寄存器为低 16
@ -53,29 +54,49 @@ public class ModbusUtils {
return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
}
/** 入库用:四舍五入保留 4 位小数 */
public static String formatFloat4Decimals(float value) {
if (Float.isNaN(value) || Float.isInfinite(value)) {
return "0.0000";
}
return BigDecimal.valueOf(value).setScale(4, RoundingMode.HALF_UP).toPlainString();
}
private static float pickAbnormalFloatCandidate(float highWordFirst, float lowWordFirst) {
int scoreHigh = scoreAbnormalFloat(highWordFirst);
int scoreLow = scoreAbnormalFloat(lowWordFirst);
if (scoreLow > scoreHigh) {
return lowWordFirst;
}
if (scoreHigh > scoreLow) {
return highWordFirst;
}
if (scoreHigh < 0) {
return 0f;
}
return highWordFirst;
}
/** 值越大越可信:占位值 -99999.9 &gt; 正常测量 &gt; 0 &gt; 字序错误的极小值 */
/**
* 值越大越可信设备占位约 ±99999 &gt; 正常测量 17.x&gt; 0
* 字序/地址偏差产生的 ±1e82.7E23E-41 等极低或极高值判为不可信
*/
private static int scoreAbnormalFloat(float value) {
if (Float.isNaN(value) || Float.isInfinite(value)) {
return -100;
return -1000;
}
if (value == 0f) {
return 0;
}
float abs = Math.abs(value);
if (abs >= 10000f) {
return 100;
if (abs >= 99900f && abs <= 100100f) {
return 1000;
}
if (abs >= 1e6f || abs < 1e-4f) {
return -1000;
}
if (abs >= 1e-6f) {
return 50;
if (abs <= 50000f) {
return 500;
}
return -100;
}

74
src/main/java/com/xujie/sys/modules/pms/service/Impl/QcServiceImpl.java

@ -4815,6 +4815,7 @@ public class QcServiceImpl implements QcService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public ArrayList<SubDetailValues> getCollectorDataByItem(QcFAIRecordData data) throws Exception{
EquipmentFolderLocation location = getCollectorLocation(data.getSite());
int port = location.getPort();
@ -4834,7 +4835,7 @@ public class QcServiceImpl implements QcService {
}
ArrayList<SubDetailValues> abnormalRows = getAbnormalCollectorData(ip, port, unitId, data);
resetCollectorAbnormalRegisters(ip, port, unitId);
//resetCollectorAbnormalRegisters(ip, port, unitId);
return abnormalRows;
}else{
logger.info(port+","+ip+","+unitId+","+baseAddr+","+groups+",");
@ -4935,6 +4936,14 @@ public class QcServiceImpl implements QcService {
return v == null ? -1 : (v & 0xFFFF);
}
private static String hexReg(Map<Integer, Integer> raw, int ref) {
Integer v = raw.get(ref);
if (v == null) {
return "null";
}
return String.format(Locale.ROOT, "%04X", v & 0xFFFF);
}
private EquipmentFolderLocation getCollectorLocation(String site) {
LambdaQueryWrapper<EquipmentFolderLocation> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(EquipmentFolderLocation::getEquipmentNo, "J001");
@ -5187,7 +5196,7 @@ public class QcServiceImpl implements QcService {
}*/
private ArrayList<SubDetailValues> getAbnormalCollectorData(String ip, int port, int unitId, QcFAIRecordData data) throws Exception {
int readStartAddr = 400;
int readCount = 195; // 覆盖 400~594单次 FC03 字数不宜超过从站上限需分批
int readCount = 196; // 覆盖 400~595第10组第5路float需595单次FC03需分批
Map<Integer, Integer> raw = ModbusUtils.readHoldingRegistersBatched(ip, port, unitId, readStartAddr, readCount);
ArrayList<SubDetailValues> subDetailValues = new ArrayList<>();
if (raw == null || raw.isEmpty()) {
@ -5205,20 +5214,32 @@ public class QcServiceImpl implements QcService {
timeParts.add(timeValue == null ? 0 : (timeValue & 0xFFFF));
}
// 异常数据地址按32位float读取高字在前406/408/410/412/414 ...
// 异常 float/低字在前自动择优屏显地址与 PDU ref 可能差 1不能固定低字在前
List<Float> 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));
int regRef = abnormalStartAddr + (i * 2);
int regRefNext = regRef + 1;
Integer reg0 = raw.get(regRef);
Integer reg1 = raw.get(regRefNext);
if (reg0 != null && reg1 != null) {
abnormalValues.add(ModbusUtils.parseAbnormalCollectorFloat(reg0, reg1));
} else {
abnormalValues.add(0F);
}
}
if (groupIdx == 0) {
logger.info("异常区原始寄存器(屏显约40406起): r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}, r{}=0x{}",
abnormalStartAddr, hexReg(raw, abnormalStartAddr),
abnormalStartAddr + 1, hexReg(raw, abnormalStartAddr + 1),
abnormalStartAddr + 2, hexReg(raw, abnormalStartAddr + 2),
abnormalStartAddr + 3, hexReg(raw, abnormalStartAddr + 3),
abnormalStartAddr + 4, hexReg(raw, abnormalStartAddr + 4),
abnormalStartAddr + 5, hexReg(raw, abnormalStartAddr + 5),
abnormalStartAddr + 6, hexReg(raw, abnormalStartAddr + 6),
abnormalStartAddr + 7, hexReg(raw, abnormalStartAddr + 7),
abnormalStartAddr + 8, hexReg(raw, abnormalStartAddr + 8),
abnormalStartAddr + 9, hexReg(raw, abnormalStartAddr + 9));
}
logger.info("获取到的数据:{},时间:{}",abnormalValues.toString(),timeParts.toString());
boolean hasAbnormal = abnormalValues.stream().anyMatch(v -> v != 0F);
@ -5239,7 +5260,7 @@ public class QcServiceImpl implements QcService {
detailValues.setIsSubmit("N");
detailValues.setSite(data.getSite());
detailValues.setNum(1);
detailValues.setSubDetailValue(String.valueOf(abnormalValues.get(i)));
detailValues.setSubDetailValue(ModbusUtils.formatFloat4Decimals(abnormalValues.get(i)));
detailValues.setSubDetailValueB(collectedTime);
detailValues.setSamplingLocationB(collectedTime);
subDetailValues.add(detailValues);
@ -5250,21 +5271,24 @@ public class QcServiceImpl implements QcService {
return subDetailValues;
}
/**
* 无工单异常采集复位300/301/302 + 10 组时间(6 寄存器)与异常 float 高字寄存器(5 ×2 字取高字地址)
*/
private void resetCollectorAbnormalRegisters(String ip, int port, int unitId) {
List<Integer> 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("开始复位");
List<Integer> resetAddrs = new ArrayList<>();
resetAddrs.add(301);
resetAddrs.add(302);
for (int groupIdx = 0; groupIdx < 10; groupIdx++) {
int timeStartAddr = 400 + (groupIdx * 20);
for (int i = 0; i < 6; i++) {
resetAddrs.add(timeStartAddr + i);
}
int abnormalStartAddr = 406 + (groupIdx * 20);
for (int i = 0; i < 5; i++) {
resetAddrs.add(abnormalStartAddr + (i * 2));
}
}
logger.info("开始复位, 共 {} 个寄存器", resetAddrs.size());
ModbusUtils.resetRegisters(ip, port, unitId, resetAddrs);
logger.info("复位结束");
}

Loading…
Cancel
Save