新增老版维尔普斯指令及数据解析

This commit is contained in:
wangshilong 2025-02-25 20:17:14 +08:00
parent b111c1d496
commit 2b4bd351b7
30 changed files with 579 additions and 135 deletions

View File

@ -0,0 +1,31 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import com.isu.gaswellwatch.utils.ByteOrderUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 09:34
*/
public class AbstractByteOrderDecodeHandler implements DecodeHandler {
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return null;
}
return ByteOrderUtils.decode(value, MapUtil.getStr(commandPointMap, "byte_order"));
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -41,7 +42,7 @@ public class Base2000YearLocalDateTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,6 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.springframework.stereotype.Component;
@ -31,7 +31,7 @@ public class ByteToStringDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,42 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Objects;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/24 20:18
*/
@Component(IEEE754DoubleDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class IEEE754DoubleDecodeHandler implements DecodeHandler {
public static final String NAME = "IEEE754Double";
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return value;
}
// 反向计算Long.toHexString(Double.doubleToRawLongBits(num))
value = String.valueOf(Double.longBitsToDouble(Long.parseLong(value, 16)));
if (Objects.nonNull(commandPointMap) && Objects.nonNull(commandPointMap.get("precision"))) {
int precision = MapUtil.getInt(commandPointMap, "precision", 0);
return new BigDecimal(value).setScale(precision, RoundingMode.HALF_UP).toString();
}
return value;
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,47 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.Objects;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/22 00:50
*/
@Component(IEEE754FloatDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class IEEE754FloatDecodeHandler implements DecodeHandler {
public static final String NAME = "IEEE754Float";
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return value;
}
value = String.valueOf(Float.intBitsToFloat((int) Long.parseLong(value, 16)));
if (Objects.nonNull(commandPointMap) && Objects.nonNull(commandPointMap.get("precision"))) {
int precision = MapUtil.getInt(commandPointMap, "precision", 0);
return new BigDecimal(value).setScale(precision, RoundingMode.HALF_UP).toString();
}
// 反向计算Long.toHexString(Float.floatToRawIntBits(num))
return value;
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
public static void main(String[] args) {
System.out.println(Double.longBitsToDouble(Long.parseLong("800358C0", 16)));
System.out.println(Float.intBitsToFloat((int) Long.parseLong("800358C0", 16)));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -33,7 +34,7 @@ public class LocalDateDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -36,7 +37,7 @@ public class LocalDateTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -32,7 +33,7 @@ public class LocalTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,35 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 整型书解析器解析器
*
* @author <a href="mailto:scwsl@foxmail.com">王仕龙</a>
* 2025/2/25 11:15
*/
@Component(LongDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class LongDecodeHandler implements DecodeHandler {
public static final String NAME = "long";
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return value;
}
return String.valueOf(Long.parseLong(value, 16));
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -32,7 +33,7 @@ public class MinuteLocalTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,13 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 10:12
*/
@Component(OneRegisterLengthByteOrderDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class OneRegisterLengthByteOrderDecodeHandler extends AbstractByteOrderDecodeHandler {
public static final String NAME = "oneRegisterLengthByteOrder";
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -37,7 +38,7 @@ public class SecondLocalTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -40,7 +41,7 @@ public class SimpleLocalDateTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,5 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -32,7 +33,7 @@ public class StringTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,14 @@
package com.isu.gaswellwatch.modbus.data.decode.impl;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 10:13
*/
@Component(TwoRegisterLengthByteOrderDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class TwoRegisterLengthByteOrderDecodeHandler extends AbstractByteOrderDecodeHandler {
public static final String NAME = "twoRegisterLengthByteOrder";
}

View File

@ -22,7 +22,7 @@ public class UnsignedNumberDecodeHandler implements DecodeHandler {
if (StringUtils.isBlank(value)) {
return value;
}
return String.valueOf(Integer.parseInt(value, 16));
return String.valueOf(Long.parseLong(value, 16));
}
@Override

View File

@ -1,6 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl.weps;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -49,6 +49,6 @@ public class WepsCurrentLocalDateTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -0,0 +1,36 @@
package com.isu.gaswellwatch.modbus.data.decode.impl.weps;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 11:36
*/
@Component(WepsCurrentStatus0xDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class WepsCurrentStatus0xDecodeHandler implements DecodeHandler {
public static final String NAME = "wepsCurrentStatus0x";
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return value;
}
// 0x8000:关井
// 0x8001:上升
// 0x8002:续流
// 0x8003:停机
return value;
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -1,41 +0,0 @@
package com.isu.gaswellwatch.modbus.data.decode.impl.weps;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/22 00:50
*/
@Component(WepsDecimalDecodeHandler.NAME + DecodeHandler.DECODE_NAME)
public class WepsDecimalDecodeHandler implements DecodeHandler {
public static final String NAME = "wepsDecimal";
@Override
public String decode(Map<String, Object> commandPointMap, String value) {
if (StringUtils.isBlank(value)) {
return value;
}
if (StringUtils.startsWith(value, ".")) {
return NumberUtils.createBigDecimal("0" + StringUtils.strip(value, "-")).toString();
} else if (StringUtils.endsWith(value, ".")) {
return NumberUtils.createBigDecimal(value + "0").toString();
} else {
String[] numbers = StringUtils.split(value, ".");
return numbers[0] + "." + Math.abs(NumberUtils.createLong(numbers[1]));
}
}
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
}
}

View File

@ -1,6 +1,6 @@
package com.isu.gaswellwatch.modbus.data.decode.impl.weps;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.ModbusMessage;
import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler;
import org.apache.commons.lang3.StringUtils;
@ -50,6 +50,6 @@ public class WepsRemainingLocalTimeDecodeHandler implements DecodeHandler {
@Override
public void decode(Map<String, Object> commandPointMap, ModbusMessage.MessagePoint point) {
point.setValue(this.decode(commandPointMap, point.getValue()));
point.setValue(this.decode(commandPointMap, MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE) ? point.getOriginalValue() : point.getValue()));
}
}

View File

@ -97,8 +97,8 @@ public class WepsPlugPersistenceHandler extends AbstractPersistenceHandler {
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 23, "tooFastCount", Types.INTEGER);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 24, "dangerousRiseTime", Types.VARCHAR);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 25, "tooFastRiseTime", Types.VARCHAR);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 26, "openWellTime", Types.DECIMAL);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 27, "closeWellTime", Types.DECIMAL);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 26, "openWellTime", Types.VARCHAR);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 27, "closeWellTime", Types.VARCHAR);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 28, "openWellCasPressure", Types.DECIMAL);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 29, "littleRiseCasPressure", Types.DECIMAL);
WepsPlugPersistenceHandler.this.setValue(ps, newRow, 30, "checkStabilityTime", Types.VARCHAR);

View File

@ -164,7 +164,6 @@ public class ModbusMessagePersistListener implements BatchMessageListener {
}
}
public void decode(ModbusMessage modbusMessage) {
Long commandId = modbusMessage.getCommandId();
String cacheName = PersistenceHandler.COMMAND_CACHE + commandId + ":points";
@ -266,7 +265,11 @@ public class ModbusMessagePersistListener implements BatchMessageListener {
for (int i = 0; i < stepSize; i++) {
messagePoint = pointMap.get(StringUtils.leftPad(String.valueOf(startAddress + i), 4, '0'));
if (MapUtil.getBool(commandPointMap, "use_hex", Boolean.FALSE)) {
values[i] = messagePoint.getOriginalValue();
if (Objects.isNull(messagePoint)) {
values[i] = StringUtils.EMPTY;
} else {
values[i] = messagePoint.getOriginalValue();
}
} else {
if (Objects.isNull(messagePoint)) {
values[i] = StringUtils.EMPTY;
@ -280,7 +283,8 @@ public class ModbusMessagePersistListener implements BatchMessageListener {
StringUtils.isBlank(format) ? StringUtils.join(values) : String.format(format, values));
}
private String decodeHighLowCommandPoint(Map<String, ModbusMessage.MessagePoint> pointMap, String decodeName,
private String decodeHighLowCommandPoint(Map<String, ModbusMessage.MessagePoint> pointMap, String
decodeName,
Map<String, Object> commandPointMap, int startAddress) {
String[] values = new String[2];
ModbusMessage.MessagePoint messagePoint;
@ -295,7 +299,8 @@ public class ModbusMessagePersistListener implements BatchMessageListener {
return highLowBinDecodeHandler.decode(commandPointMap, StringUtils.join(values));
}
private String decodeHighLowStepCommandPoint(Map<String, ModbusMessage.MessagePoint> pointMap, String decodeName,
private String decodeHighLowStepCommandPoint(Map<String, ModbusMessage.MessagePoint> pointMap, String
decodeName,
Map<String, Object> commandPointMap, int startAddress, int stepSize) {
String[] values = new String[stepSize];
ModbusMessage.MessagePoint highPoint;

View File

@ -0,0 +1,71 @@
package com.isu.gaswellwatch.utils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 20:10
*/
public class ByteOrderUtils {
/**
* @param hexString
* @param byteOrder 可选值AB,BA,ABCD,CDAB,DCBA等
* @return
*/
public static String decode(String hexString, String byteOrder) {
if (StringUtils.isBlank(byteOrder) || StringUtils.equalsAnyIgnoreCase(byteOrder, "AB", "ABCD")) {
return hexString;
}
AtomicInteger atomicInteger = new AtomicInteger(0);
Map<Character, Integer> byteOrderMap = new TreeMap<>(Character::compare);
byteOrder.chars().forEach(i -> byteOrderMap.put((char) i, atomicInteger.getAndIncrement()));
int size = hexString.length() / 2;
String[] byteOrderChars = new String[size];
for (int i = 0; i < size; i++) {
byteOrderChars[i] = hexString.substring(i * 2, i * 2 + 2);
}
if (hexString.length() >= byteOrder.length()) {
return byteOrderMap.values().stream().map(idx -> byteOrderChars[idx]).collect(Collectors.joining());
} else {
return hexString;
}
}
/**
* @param hexString
* @param byteOrder 可选值AB,BA,ABCD,CDAB,DCBA等
* @return
*/
public static String encode(String hexString, String byteOrder) {
if (StringUtils.isBlank(byteOrder) || StringUtils.equalsAnyIgnoreCase(byteOrder, "AB", "ABCD")) {
return hexString;
}
int length = byteOrder.length() * 2;
if (hexString.length() < length) {
hexString = StringUtils.leftPad(hexString, length, '0');
}
AtomicInteger atomicInteger = new AtomicInteger(0);
Map<Character, Integer> byteOrderMap = new TreeMap<>(Character::compare);
byteOrder.chars().forEach(i -> byteOrderMap.put((char) i, atomicInteger.getAndIncrement()));
int size = hexString.length() / 2;
String[] byteOrderChars = new String[size];
for (int i = 0; i < size; i++) {
byteOrderChars[i] = hexString.substring(i * 2, i * 2 + 2);
}
if (hexString.length() >= byteOrder.length()) {
return byteOrderMap.values().stream().map(idx -> byteOrderChars[idx]).collect(Collectors.joining());
} else {
return hexString;
}
}
}

View File

@ -1,14 +1,17 @@
package com.isu.gaswellwatch.vo.command.weps;
import com.isu.gaswellwatch.dto.modbus.ModbusCommandDto;
import com.isu.gaswellwatch.utils.ByteOrderUtils;
import com.isu.gaswellwatch.vo.command.Command;
import com.isu.gaswellwatch.vo.command.Timing;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -25,86 +28,118 @@ public class MiWepsPlugControl extends Command implements Timing {
@Serial
private static final long serialVersionUID = -7540015879950965127L;
// private Integer gasWellNumber; // 气井编号
private Integer depthOfLockDevice; // 卡定器深度 单位
private Integer arrivingSensor; // 到达传感器 0/1禁用/启用
private Integer zigbee; // Zigbee 0/1禁用/启用
private Integer pulseWidth; // 脉冲宽度 驱动电磁阀使用
private Integer plugRisingSpeed; // 上升速度 /分钟
private Integer plugTooFastSpeed; // 过快速度 /分钟
private Integer plugTooSlowSpeed; // 过缓速度 /分钟
// private Integer gasWellName; // 气井名称
// 分段
private Integer oilAndCasDataCollectionInterval; // 套压数据采集间隔 0每5秒采样1每10秒采样2每15秒采样3每30秒采样4每1秒采样5每2秒采样6每3秒采样7每4秒采样
private Integer storeDataIntervalOnOpenWell; // 数据存储间隔开井期间 0每1分钟存储1每5分钟存储2每10分钟存储3每15分钟存储4每30秒存储5每15秒存储6每5秒存储
private Integer storeDataIntervalOnCloseWell; // 数据存储间隔关井期间 0每1分钟存储1每5分钟存储2每10分钟存储3每15分钟存储4每30秒存储5每15秒存储6每5秒存储
// 分段
// private Integer communicationPowerThreshold; // 通信电量门限 Zigbee通讯使用
// private Integer reserve1; // 保留 Zigbee通讯使用
// private Integer startTimeOfDaytime; // 白天起始时间 Zigbee通讯使用
// private Integer endTimeOfDaytime; // 白天结束时间 Zigbee通讯使用
// 1005
private Integer depthOfLockDevice; // 卡定器深度 单位 -- 气井深度
// 1036
private Integer controlWorkTime; // 控制器工作状态 0生产模式1常开模式2常关模式
// 1037
private Integer produceMode; // 生产制度设置 0定时开关井1时间优化模式2压力微升模式3压力回升模式4压力跌落模式
private String plungerRiseTime; // 上升时间 单位
private String dangerousRiseTime; // 危险上升时间 单位
private String tooFastRiseTime; // 过快上升时间 单位
private String tooSlowRiseTime; // 过缓上升时间 单位
// 1039
private String dangerousRiseTime; // 危险上升时间 单位HH:mm:ss
// 1040
private String tooFastRiseTime; // 过快上升时间 单位HH:mm:ss
// 1042
private Integer tooFastCount; // 过快次数
private String tooFastRaiseOpenWellTime; // 过快增加开井时间 单位
private String tooFastLowerCloseWellTime; // 过快减少关井时间 单位
private String tooSlowLowerOpenWellTime; // 过缓减少开井时间 单位
private String tooSlowRaiseCloseWellTime; // 过缓增加关井时间 单位
private String checkStabilityTime; // 检测稳定时间 单位
private String minCloseWellTime; // 最小关井时间 单位
private String maxCloseWellTime; // 最大关井时间 单位
private String wellCloseTimeNotReachedDuration; // 未到达关井时间 单位
private String minOpenWellTime; // 最小开井时间 单位
private String maxOpenWellTime; // 最大开井时间 单位
private String afterFlowTime; // 续流时间 单位
private String notReachedFlowTime; // 未到续流时间 单位
private String closeTime; // 关井时间 单位
private String openTime; // 开井时间 单位
private BigDecimal openPressure; // 开井压力 单位MPa
private BigDecimal closePressure; // 关井压力 单位MPa
private BigDecimal littleRisePressure; // 微升压力 单位MPa
// 1062 - 2
private String closeTime; // 关井时间 单位HH:mm:ss
// 1064 - 2
private String openTime; // 开井时间 单位HH:mm:ss
// 1072
private Integer gasCollectionMode; // 集气模式 0低压集气模式1高压集气模式
// private Integer reserve2; // 保留
// 分段
private BigDecimal protectionPressure; // 保护压力 单位MPa
// 1074 - 2
private BigDecimal protectionPressure; // 保护压力 单位MPa当集气模式为低压集气模式时该保护压力为低压保护压力当集气模式为高压集气模式该保护压力为高压保护压力
public MiWepsPlugControl() {
this.setCode("MI_WEPS.PLUG.CONTROL");
}
public void setDangerousRiseTime(String dangerousRiseTime) {
this.dangerousRiseTime = this.timingValidate(dangerousRiseTime, "dangerousRiseTime");
}
public void setTooFastRiseTime(String tooFastRiseTime) {
this.tooFastRiseTime = this.timingValidate(tooFastRiseTime, "tooFastRiseTime");
}
public void setOpenTime(String openTime) {
this.openTime = this.timingValidate(openTime, "openTime");
}
public void setCloseTime(String closeTime) {
this.closeTime = this.timingValidate(closeTime, "closeTime");
}
@Override
protected Collection<ModbusCommandDto> builderModbusCommand() {
List<ModbusCommandDto> commandList = new ArrayList<>(7);
StringBuilder command = new StringBuilder(250);
// 100
// 1005
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 003F 0013 26
command.append("0110003F001326");
// command.append(StringUtils.leftPad(Integer.toHexString(this.runMode), 4, "0"));
// command.append(StringUtils.leftPad(Integer.toHexString(this.wellStatus), 4, "0"));
// command.append(StringUtils.leftPad(Integer.toHexString(this.gasCollectionMethod), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.highPressureProtection.multiply(ONE_HUNDRED).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.lowPressureProtection.multiply(ONE_HUNDRED).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Integer.toHexString(this.tooFastCount), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.dangerousRiseTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.tooFastRiseTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.openWellTime.multiply(ONE_SIXTY).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.closeWellTime.multiply(ONE_SIXTY).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.openWellCasPressure.multiply(ONE_HUNDRED).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.littleRiseCasPressure.multiply(ONE_HUNDRED).longValue()), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.checkStabilityTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.minCloseWellTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.maxCloseWellTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.minOpenWellTime)), 4, "0"));
// command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.maxOpenWellTime)), 4, "0"));
// command.append(StringUtils.leftPad(Integer.toHexString(this.wellDepth), 4, "0"));
// command.append(StringUtils.leftPad(Integer.toHexString(this.produceMode), 4, "0"));
return List.of(ModbusCommandDto.builder().command(command.toString()).length(16).build());
// 01 10 03ED 0001 02
command.append("011003ED000102").append(StringUtils.leftPad(Integer.toHexString(this.depthOfLockDevice), 4, "0"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1036
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 040C 0002 04
command.append("0110040C000204")
.append(StringUtils.leftPad(Integer.toHexString(this.controlWorkTime), 4, "0"))
.append(StringUtils.leftPad(Integer.toHexString(this.produceMode), 4, "0"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1039
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 040F 0002 04
command.append("0110040F000204")
.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.dangerousRiseTime)), 4, "0"))
.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.dangerousRiseTime)), 4, "0"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1042
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 0412 0001 02
command.append("01100412000102")
.append(StringUtils.leftPad(Integer.toHexString(this.tooFastCount), 4, "0"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1062
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 0426 0004 08
command.append("01100426000408")
.append(ByteOrderUtils.encode(Long.toHexString(this.toSeconds(this.closeTime)), "CDAB"))
.append(ByteOrderUtils.encode(Long.toHexString(this.toSeconds(this.openTime)), "CDAB"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1072
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 0430 0001 02
command.append("01100430000102")
.append(StringUtils.leftPad(Integer.toHexString(this.gasCollectionMode), 4, "0"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
command.setLength(0);
// 1074
// 地址码 功能码 起始地址 连续长度 连续字长
// 01 10 0432 0002 04
command.append("01100432000204")
.append(ByteOrderUtils.encode(Long.toHexString(Float.floatToRawIntBits(this.protectionPressure.floatValue())), "CDAB"));
commandList.add(ModbusCommandDto.builder().command(command.toString()).length(16).build());
return commandList;
}
}

View File

@ -34,8 +34,8 @@ public class WepsPlugControl extends Command implements Timing {
private Integer tooFastCount;
private String dangerousRiseTime;
private String tooFastRiseTime;
private BigDecimal openWellTime;
private BigDecimal closeWellTime;
private String openWellTime;
private String closeWellTime;
private BigDecimal openWellCasPressure;
private BigDecimal littleRiseCasPressure;
private String checkStabilityTime;
@ -50,6 +50,14 @@ public class WepsPlugControl extends Command implements Timing {
this.setCode("WEPS.PLUG.CONTROL");
}
public void setOpenWellTime(String openWellTime) {
this.openWellTime = this.timingValidate(openWellTime, "openWellTime");
}
public void setCloseWellTime(String closeWellTime) {
this.closeWellTime = this.timingValidate(closeWellTime, "closeWellTime");
}
public void setDangerousRiseTime(String dangerousRiseTime) {
this.dangerousRiseTime = this.timingValidate(dangerousRiseTime, "dangerousRiseTime");
}
@ -94,8 +102,8 @@ public class WepsPlugControl extends Command implements Timing {
command.append(StringUtils.leftPad(Integer.toHexString(this.tooFastCount), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.dangerousRiseTime)), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.tooFastRiseTime)), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.openWellTime.multiply(ONE_SIXTY).longValue()), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.closeWellTime.multiply(ONE_SIXTY).longValue()), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.openWellTime)), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.toMinutes(this.closeWellTime)), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.openWellCasPressure.multiply(ONE_HUNDRED).longValue()), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.littleRiseCasPressure.multiply(ONE_HUNDRED).longValue()), 4, "0"));
command.append(StringUtils.leftPad(Long.toHexString(this.toSeconds(this.checkStabilityTime)), 4, "0"));

View File

@ -275,3 +275,77 @@ SET `command_id` = 10302,
`format` = NULL,
`decode_name` = 'byteToString'
WHERE `id` = 13208;
update command_points
set format = null,
decode_name = 'IEEE754Float'
where decode_name = 'wepsDecimal';
update command_points
set factor = null,
`precision` = null,
decode_name = 'minuteLocalTime'
where id in (13021, 13022);
ALTER TABLE `t_device_data_50001`
MODIFY COLUMN `open_well_time` varchar (10) NULL DEFAULT NULL COMMENT '开井时间设置分钟HH:mm' AFTER `too_fast_rise_time`,
MODIFY COLUMN `close_well_time` varchar (10) NULL DEFAULT NULL COMMENT '关井时间设置分钟HH:mm' AFTER `open_well_time`;
update t_device_data_50001
set open_well_time = CONCAT(LPAD(CEILING(open_well_time), 2, '0'), ':',
LPAD(open_well_time * 60 - (CEILING(open_well_time) * 60), 2, '0'), ':00'),
close_well_time = CONCAT(LPAD(CEILING(close_well_time), 2, '0'), ':',
LPAD(close_well_time * 60 - (CEILING(close_well_time) * 60), 2, '0'), ':00');
ALTER TABLE `command_points`
ADD COLUMN `byte_order` varchar(5) NULL COMMENT '字节顺序默认AB|ABCD' AFTER `use_hex`;
update `command_points`
set byte_order = 'CDAB',
`use_hex` = b'1',
decode_name = case
when LENGTH(TRIM(decode_name)) > 0 then CONCAT('twoRegisterLengthByteOrder,', decode_name)
else 'twoRegisterLengthByteOrder' end
where command_id in (10301, 10302)
and step_size = 2
and id not in (13103);
update command_points
Set decode_name = REPLACE(decode_name, ',highLowBin', ',long')
where command_id in (10301, 10302)
and step_size = 2
and id not in (13103);
UPDATE `gas_well_watch`.`command_points`
SET `command_id` = 10301,
`field` = 'currentStatus0x',
`name` = '当前状态0x',
`details` = '0x8000:关井0x8001:上升0x8002:续流0x8003:停机',
`start_address` = 9,
`step_size` = 1,
`factor` = NULL,
`precision` = NULL,
`use_hex` = b'1',
`byte_order` = '',
`format` = NULL,
`decode_name` = 'wepsCurrentStatus0x'
WHERE `id` = 13104;
update command_points
set `precision` = 2
where decode_name like '%IEEE754Double%';
UPDATE `gas_well_watch`.`command_points`
SET `command_id` = 10302,
`field` = 'tooFastCount',
`name` = '过快次数',
`details` = NULL,
`start_address` = 1042,
`step_size` = 1,
`factor` = NULL,
`precision` = NULL,
`use_hex` = NULL,
`byte_order` = NULL,
`format` = NULL,
`decode_name` = NULL
WHERE `id` = 13222;

View File

@ -26,8 +26,8 @@ CREATE TABLE `$TableName$`
`too_fast_count` int NULL DEFAULT NULL COMMENT '过快次数设置;次',
`dangerous_rise_time` varchar(10) NULL DEFAULT NULL COMMENT '危险上升时间HH:mm:ss',
`too_fast_rise_time` varchar(10) NULL DEFAULT NULL COMMENT '过快上升时间HH:mm:ss',
`open_well_time` decimal(10, 2) NULL DEFAULT NULL COMMENT '开井时间设置;小时',
`close_well_time` decimal(10, 2) NULL DEFAULT NULL COMMENT '关井时间设置;小时',
`open_well_time` varchar NULL DEFAULT NULL COMMENT '开井时间设置;分钟HH:mm',
`close_well_time` varchar NULL DEFAULT NULL COMMENT '关井时间设置;分钟HH:mm',
`open_well_cas_pressure` decimal(10, 2) NULL DEFAULT NULL COMMENT '套压开井压力MPa压力优化微升模式',
`little_rise_cas_pressure` decimal(10, 2) NULL DEFAULT NULL COMMENT '套压微升压力MPa压力优化微升模式',
`check_stability_time` varchar(10) NULL DEFAULT NULL COMMENT '检测稳定时间HH:mm:ss',

View File

@ -0,0 +1,35 @@
package com.isu.gaswellwatch;
import cn.hutool.core.map.MapUtil;
import com.isu.gaswellwatch.modbus.data.decode.impl.AbstractByteOrderDecodeHandler;
import com.isu.gaswellwatch.utils.ByteOrderUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Map;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/25 19:57
*/
public class ByteOrderTest {
@Test
public void byteOrderDecodeTest() {
Map<String, Object> commandPointMap = MapUtil.newHashMap();
commandPointMap.put("byte_order", "CDAB");
AbstractByteOrderDecodeHandler abstractByteOrderDecodeHandler = new AbstractByteOrderDecodeHandler();
String value = abstractByteOrderDecodeHandler.decode(commandPointMap, "02580000");
Assertions.assertEquals(Long.parseLong(value, 16), 600L);
}
@Test
public void byteOrderEncodeTest() {
long seconds = 600;
String testHexString = "02580000";
Assertions.assertEquals(ByteOrderUtils.encode(Long.toHexString(seconds), "CDAB"), testHexString);
}
}

View File

@ -0,0 +1,30 @@
package com.isu.gaswellwatch;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* @author <a href="mailto:shilong.wang@alpha-ess.com">王仕龙</a>
* 2025/2/24 20:05
*/
public class IEEE754FloatTest {
@Test
public void testIEEE754Float() {
float number = 235.85213f;
String hexString = "436BDA25";
Assertions.assertEquals(number, Float.intBitsToFloat(Integer.parseInt(hexString, 16)));
Assertions.assertEquals(hexString, Integer.toHexString(Float.floatToRawIntBits(number)).toUpperCase());
}
@Test
public void testIEEE754Double() {
double number = 4.065528388965132E18;
String hexString = "43CC35D443CC4433";
Assertions.assertEquals(number, Double.longBitsToDouble(Long.parseLong(hexString, 16)));
Assertions.assertEquals(hexString, Long.toHexString(Double.doubleToRawLongBits(number)).toUpperCase());
}
}

View File

@ -4,6 +4,7 @@ package com.isu.gaswellwatch;
import cn.hutool.json.JSONUtil;
import com.isu.gaswellwatch.modbus.data.listener.DynamicRabbitListener;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.amqp.core.Message;
@ -43,8 +44,8 @@ public class MIWrpsDecodeTest {
Mockito.doReturn(testMessageProperties).when(testMessage10302).getMessageProperties();
Mockito.doReturn("/modbus/collect/0").when(testMessageProperties).getConsumerQueue();
this.dynamicRabbitListener.getComposeListener().onMessage(testMessage10301);
this.dynamicRabbitListener.getComposeListener().onMessage(testMessage10302);
Assertions.assertDoesNotThrow(() -> this.dynamicRabbitListener.getComposeListener().onMessage(testMessage10301));
Assertions.assertDoesNotThrow(() -> this.dynamicRabbitListener.getComposeListener().onMessage(testMessage10302));
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));