diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/PersistenceHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/PersistenceHandler.java index 1c5efd0..ab35dfa 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/PersistenceHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/PersistenceHandler.java @@ -7,7 +7,10 @@ package com.isu.gaswellwatch.modbus.data; * 2024/11/23 11:53 */ public interface PersistenceHandler { - public static final String MODBUS_DEVICE_TYPE = "KNPCV1"; + String KNPCV1_MODBUS_TYPE = "knpc"; + String ETC_MODBUS_TYPE = "etc"; + String SCSS_MODBUS_TYPE = "scss"; + String DEVICE_INFO_CACHE = "info:device:"; String DEVICE_DATA_CACHE = "data:device:"; void createTable(String tableName, Long deviceId); diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Redis2DBPersistenceService.java b/src/main/java/com/isu/gaswellwatch/modbus/data/Redis2DBPersistenceService.java similarity index 70% rename from src/main/java/com/isu/gaswellwatch/modbus/data/impl/Redis2DBPersistenceService.java rename to src/main/java/com/isu/gaswellwatch/modbus/data/Redis2DBPersistenceService.java index d999fc0..e51dc89 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Redis2DBPersistenceService.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/Redis2DBPersistenceService.java @@ -1,8 +1,7 @@ -package com.isu.gaswellwatch.modbus.data.impl; +package com.isu.gaswellwatch.modbus.data; import cn.hutool.core.map.MapUtil; import com.isu.gaswellwatch.entity.Response; -import com.isu.gaswellwatch.modbus.data.PersistenceHandler; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; @@ -34,8 +33,9 @@ import java.util.stream.Collectors; @SuppressWarnings("all") public class Redis2DBPersistenceService { - private static final String EXISTS_TABLE_SQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA" + - " IN ('gaswellwatch', 'gas_well_watch') AND TABLE_NAME='$TableName$'"; + private static final String EXISTS_TABLE_SQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA" + + " IN ('gaswellwatch', 'gas_well_watch') AND TABLE_NAME='$TableName$'"; + private static final String DEVICE_INFO_SQL = "SELECT * from device where id = "; @Resource private JdbcTemplate jdbcTemplate; @Resource(name = "stringRedisTemplate") @@ -65,10 +65,19 @@ public class Redis2DBPersistenceService { continue; } if (Objects.nonNull(idGatewayMappingMap)) { - operations.put(PersistenceHandler.DEVICE_DATA_CACHE + deviceId, - "online", String.valueOf(idGatewayMappingMap.containsKey(deviceId))); + operations.put(PersistenceHandler.DEVICE_DATA_CACHE + deviceId, "online", + String.valueOf(idGatewayMappingMap.containsKey(deviceId))); } - persistenceHandler = persistenceHandlerMap.get("KNPCV1"); + String modbusDeviceType = (String) operations.get(PersistenceHandler.DEVICE_INFO_CACHE + deviceId, "product"); + if (StringUtils.isEmpty(modbusDeviceType)) { + Map deviceInfo = this.jdbcTemplate.queryForMap(DEVICE_INFO_SQL + deviceId); + Map cacheDeviceInfo = new HashMap<>(deviceInfo.size()); + deviceInfo.forEach((key, value) -> cacheDeviceInfo.put(key, Objects.isNull(value) ? null : String.valueOf(value))); + modbusDeviceType = (String) cacheDeviceInfo.get("product"); + operations.putAll(PersistenceHandler.DEVICE_INFO_CACHE + deviceId, cacheDeviceInfo); + } + + persistenceHandler = persistenceHandlerMap.get(PersistenceHandler.KNPCV1_MODBUS_TYPE); tableName = "t_device_data_" + deviceId; existsTableList = this.jdbcTemplate.queryForList(StringUtils.replace(EXISTS_TABLE_SQL, "$TableName$", tableName)); if (ObjectUtils.isEmpty(existsTableList) @@ -84,18 +93,14 @@ public class Redis2DBPersistenceService { private Map getOnlineGateway() { try { RequestEntity request = RequestEntity.get("http://127.0.0.1:9999/modbus-tcp/online").build(); - ResponseEntity>> response = this.restTemplate.exchange(request, - new ParameterizedTypeReference>>() { - }); - if (Objects.isNull(response) - || Objects.isNull(response.getBody()) - || ObjectUtils.isEmpty(response.getBody().getData())) { + ResponseEntity>> response = this.restTemplate.exchange(request, new ParameterizedTypeReference>>() { + }); + if (Objects.isNull(response) || Objects.isNull(response.getBody()) || ObjectUtils.isEmpty(response.getBody().getData())) { return null; } - List> idGatewayMappingList = this.jdbcTemplate - .queryForList("select id, gateway_sn from devices where gateway_sn in (" + - response.getBody().getData().stream().map(value -> "'" + value + "'") - .collect(Collectors.joining(",")) + ")"); + List> idGatewayMappingList = this.jdbcTemplate.queryForList("select id, gateway_sn" + + " from device where gateway_sn in (" + + response.getBody().getData().stream().map(value -> "'" + value + "'").collect(Collectors.joining(",")) + ")"); if (ObjectUtils.isEmpty(idGatewayMappingList)) { return null; } diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/DecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/DecodeHandler.java index 070d73c..5164bb1 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/DecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/DecodeHandler.java @@ -13,6 +13,7 @@ import java.util.Map; * 2024/11/23 11:20 */ public interface DecodeHandler { + String DECODE_NAME = "DecodeHandler"; Logger logger = LoggerFactory.getLogger("com.isu.gaswellwatch.decode"); diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/ComposeDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/ComposeDecodeHandler.java new file mode 100644 index 0000000..2504825 --- /dev/null +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/ComposeDecodeHandler.java @@ -0,0 +1,35 @@ +package com.isu.gaswellwatch.modbus.data.decode.impl; + +import com.isu.gaswellwatch.modbus.data.ModbusMessage; +import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; + +import java.util.Collection; +import java.util.Map; + +/** + * @author 王仕龙 + * 2024/11/25 16:31 + */ +public class ComposeDecodeHandler implements DecodeHandler { + + public final Collection collection; + + public ComposeDecodeHandler(Collection collection) { + this.collection = collection; + } + + @Override + public String decode(Map commandPointMap, String value) { + for (DecodeHandler handler : this.collection) { + value = handler.decode(commandPointMap, value); + } + return value; + } + + @Override + public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { + for (DecodeHandler handler : this.collection) { + handler.decode(commandPointMap, point); + } + } +} diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/FactorDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/FactorDecodeHandler.java index 7400676..e1d1f3b 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/FactorDecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/FactorDecodeHandler.java @@ -3,7 +3,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 lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -23,10 +22,10 @@ import java.util.Map; * @author 王仕龙 * 2024/11/24 21:23 */ -@Slf4j -@SuppressWarnings("all") -@Component("factorDecodeHandler") +@Component(FactorDecodeHandler.NAME + DecodeHandler.DECODE_NAME) public class FactorDecodeHandler implements DecodeHandler { + public static final String NAME = "factor"; + @Override public String decode(Map commandPointMap, String value) { @@ -35,11 +34,11 @@ public class FactorDecodeHandler implements DecodeHandler { @Override public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { - point.setValue(decode(commandPointMap, point.getParseValue())); + point.setValue(this.decode(commandPointMap, point.getParseValue())); String factorStr = MapUtil.getStr(commandPointMap, "factor"); if (StringUtils.isNotBlank(factorStr) && StringUtils.isNotBlank(point.getParseValue())) { BigDecimal factor = new BigDecimal(factorStr); - BigDecimal value = new BigDecimal(point.getParseValue()); + BigDecimal value = new BigDecimal(point.getValue()); int precision = MapUtil.getInt(commandPointMap, "precision", 0); switch (factor.compareTo(BigDecimal.ZERO)) { case -1 -> point.setValue(value.multiply(factor.abs()).toString()); diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/HighLowBinDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/HighLowBinDecodeHandler.java new file mode 100644 index 0000000..49f9178 --- /dev/null +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/HighLowBinDecodeHandler.java @@ -0,0 +1,32 @@ +package com.isu.gaswellwatch.modbus.data.decode.impl; + +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; + +/** + * 高低位4字节解析器 + * + * @author 王仕龙 + * 2024/11/25 16:36 + */ +@Component(HighLowBinDecodeHandler.NAME + DecodeHandler.DECODE_NAME) +public class HighLowBinDecodeHandler implements DecodeHandler { + + public static final String NAME = "highLowBin"; + + @Override + public String decode(Map commandPointMap, String value) { + return StringUtils.isBlank(value) ? value : NumberUtils.createLong(value).toString(); + } + + @Override + public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { + point.setValue(this.decode(commandPointMap, point.getValue())); + } + +} diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateDecodeHandler.java index 4b78c13..52ea072 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateDecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateDecodeHandler.java @@ -2,7 +2,6 @@ package com.isu.gaswellwatch.modbus.data.decode.impl; import com.isu.gaswellwatch.modbus.data.ModbusMessage; import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.time.LocalDate; @@ -15,10 +14,10 @@ import java.util.Map; * @author 王仕龙 * 2024/11/25 11:51 */ -@Slf4j -@SuppressWarnings("all") -@Component("localDateDecodeHandler") +@Component(LocalDateDecodeHandler.NAME + DecodeHandler.DECODE_NAME) public class LocalDateDecodeHandler implements DecodeHandler { + public static final String NAME = "localDate"; + public static final DateTimeFormatter IN_FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d"); public static final DateTimeFormatter OUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @@ -30,7 +29,7 @@ public class LocalDateDecodeHandler implements DecodeHandler { @Override public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { - point.setValue(decode(commandPointMap, point.getParseValue())); + point.setValue(this.decode(commandPointMap, point.getValue())); } } diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateTimeDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateTimeDecodeHandler.java index 8c86993..c9a90da 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateTimeDecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalDateTimeDecodeHandler.java @@ -2,7 +2,6 @@ package com.isu.gaswellwatch.modbus.data.decode.impl; import com.isu.gaswellwatch.modbus.data.ModbusMessage; import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @@ -15,10 +14,10 @@ import java.util.Map; * @author 王仕龙 * 2024/11/24 21:34 */ -@Slf4j -@SuppressWarnings("all") -@Component("localDateTimeDecodeHandler") +@Component(LocalDateTimeDecodeHandler.NAME + DecodeHandler.DECODE_NAME) public class LocalDateTimeDecodeHandler implements DecodeHandler { + public static final String NAME = "localDateTime"; + public static final DateTimeFormatter IN_FORMATTER = DateTimeFormatter.ofPattern("yyyy-M-d H:m:s"); public static final DateTimeFormatter OUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @@ -30,7 +29,7 @@ public class LocalDateTimeDecodeHandler implements DecodeHandler { @Override public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { - point.setValue(decode(commandPointMap, point.getParseValue())); + point.setValue(this.decode(commandPointMap, point.getValue())); } } diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalTimeDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalTimeDecodeHandler.java index 37ed01a..9474305 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalTimeDecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/LocalTimeDecodeHandler.java @@ -2,7 +2,6 @@ package com.isu.gaswellwatch.modbus.data.decode.impl; import com.isu.gaswellwatch.modbus.data.ModbusMessage; import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; -import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.time.LocalTime; @@ -15,10 +14,9 @@ import java.util.Map; * @author 王仕龙 * 2024/11/25 11:58 */ -@Slf4j -@SuppressWarnings("all") -@Component("localTimeDecodeHandler") +@Component(LocalTimeDecodeHandler.NAME + DecodeHandler.DECODE_NAME) public class LocalTimeDecodeHandler implements DecodeHandler { + public static final String NAME = "localTime"; public static final DateTimeFormatter IN_FORMATTER = DateTimeFormatter.ofPattern("H:m:s"); public static final DateTimeFormatter OUT_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); @@ -30,7 +28,7 @@ public class LocalTimeDecodeHandler implements DecodeHandler { @Override public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { - point.setValue(decode(commandPointMap, point.getParseValue())); + point.setValue(this.decode(commandPointMap, point.getValue())); } } diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/SignedNumberDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/SignedNumberDecodeHandler.java new file mode 100644 index 0000000..acb0ddc --- /dev/null +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/SignedNumberDecodeHandler.java @@ -0,0 +1,34 @@ +package com.isu.gaswellwatch.modbus.data.decode.impl; + +import com.isu.gaswellwatch.modbus.data.ModbusMessage; +import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; +import com.isu.gaswellwatch.utils.ReverseComplementCodeUtils; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 有符号整数转换 + * + * @author 王仕龙 + * 2024/11/25 16:24 + */ +@Component(SignedNumberDecodeHandler.NAME + DecodeHandler.DECODE_NAME) +public class SignedNumberDecodeHandler implements DecodeHandler { + public static final String NAME = "signedNumber"; + + @Override + public String decode(Map commandPointMap, String value) { + int decimalNumber = Integer.parseInt(value, 16); + String binaryNumber = Integer.toBinaryString(decimalNumber); + binaryNumber = ReverseComplementCodeUtils.binOriginalToReverse(binaryNumber); + binaryNumber = ReverseComplementCodeUtils.binReverseToComplement(binaryNumber, "1"); + return ReverseComplementCodeUtils.binComplementToDec(binaryNumber); + } + + @Override + public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { + point.setValue(this.decode(commandPointMap, point.getParseValue())); + } + +} diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/StringTimeDecodeHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/StringTimeDecodeHandler.java index 3458295..b9e013f 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/StringTimeDecodeHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/decode/impl/StringTimeDecodeHandler.java @@ -2,7 +2,6 @@ package com.isu.gaswellwatch.modbus.data.decode.impl; import com.isu.gaswellwatch.modbus.data.ModbusMessage; import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -17,10 +16,9 @@ import java.util.stream.Collectors; * @author 王仕龙 * 2024/11/24 21:38 */ -@Slf4j -@SuppressWarnings("all") -@Component("stringTimeDecodeHandler") +@Component(StringTimeDecodeHandler.NAME + DecodeHandler.DECODE_NAME) public class StringTimeDecodeHandler implements DecodeHandler { + public static final String NAME = "stringTime"; @Override public String decode(Map commandPointMap, String value) { @@ -34,7 +32,7 @@ public class StringTimeDecodeHandler implements DecodeHandler { @Override public void decode(Map commandPointMap, ModbusMessage.MessagePoint point) { - point.setValue(decode(commandPointMap, point.getParseValue())); + point.setValue(this.decode(commandPointMap, point.getValue())); } } diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Knpcv1PersistenceHandler.java b/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Knpcv1PersistenceHandler.java index 81e29a2..71ed93c 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Knpcv1PersistenceHandler.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/impl/Knpcv1PersistenceHandler.java @@ -26,7 +26,7 @@ import java.util.Objects; * @author 王仕龙 * 2024/11/24 17:33 */ -@Component(PersistenceHandler.MODBUS_DEVICE_TYPE) +@Component(PersistenceHandler.KNPCV1_MODBUS_TYPE) public class Knpcv1PersistenceHandler implements PersistenceHandler { @Resource diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ComposeModbusMessageListener.java b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ComposeModbusMessageListener.java similarity index 94% rename from src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ComposeModbusMessageListener.java rename to src/main/java/com/isu/gaswellwatch/modbus/data/listener/ComposeModbusMessageListener.java index 834ca26..f2f384b 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ComposeModbusMessageListener.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ComposeModbusMessageListener.java @@ -1,4 +1,4 @@ -package com.isu.gaswellwatch.modbus.data.decode.listener; +package com.isu.gaswellwatch.modbus.data.listener; import com.isu.gaswellwatch.utils.SpringUtil; import org.springframework.amqp.core.BatchMessageListener; diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/DynamicRabbitListener.java b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/DynamicRabbitListener.java similarity index 97% rename from src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/DynamicRabbitListener.java rename to src/main/java/com/isu/gaswellwatch/modbus/data/listener/DynamicRabbitListener.java index 99891a9..7baac89 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/DynamicRabbitListener.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/DynamicRabbitListener.java @@ -1,4 +1,4 @@ -package com.isu.gaswellwatch.modbus.data.decode.listener; +package com.isu.gaswellwatch.modbus.data.listener; /** * @author 王仕龙 diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessageBackupListener.java b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessageBackupListener.java similarity index 97% rename from src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessageBackupListener.java rename to src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessageBackupListener.java index dd604c0..0e52b8b 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessageBackupListener.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessageBackupListener.java @@ -1,4 +1,4 @@ -package com.isu.gaswellwatch.modbus.data.decode.listener; +package com.isu.gaswellwatch.modbus.data.listener; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.IOUtils; diff --git a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessagePersistListener.java b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessagePersistListener.java similarity index 65% rename from src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessagePersistListener.java rename to src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessagePersistListener.java index 5ee9e8a..bbb82d6 100644 --- a/src/main/java/com/isu/gaswellwatch/modbus/data/decode/listener/ModbusMessagePersistListener.java +++ b/src/main/java/com/isu/gaswellwatch/modbus/data/listener/ModbusMessagePersistListener.java @@ -1,10 +1,12 @@ -package com.isu.gaswellwatch.modbus.data.decode.listener; +package com.isu.gaswellwatch.modbus.data.listener; import cn.hutool.core.map.MapUtil; import cn.hutool.json.JSONUtil; import com.isu.gaswellwatch.modbus.data.ModbusMessage; import com.isu.gaswellwatch.modbus.data.PersistenceHandler; import com.isu.gaswellwatch.modbus.data.decode.DecodeHandler; +import com.isu.gaswellwatch.modbus.data.decode.impl.ComposeDecodeHandler; +import com.isu.gaswellwatch.modbus.data.decode.impl.HighLowBinDecodeHandler; import com.isu.gaswellwatch.modbus.data.decode.impl.LocalDateTimeDecodeHandler; import com.serotonin.modbus4j.code.FunctionCode; import com.serotonin.modbus4j.msg.*; @@ -27,10 +29,7 @@ import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; /** * @author 王仕龙 @@ -49,6 +48,9 @@ public class ModbusMessagePersistListener implements BatchMessageListener { private JdbcTemplate jdbcTemplate; @Resource(name = "stringRedisTemplate") private RedisTemplate redisTemplate; + + @Resource(name = HighLowBinDecodeHandler.NAME + DecodeHandler.DECODE_NAME) + private DecodeHandler highLowBinDecodeHandler; @Resource private Map decodeHandlerMap; @@ -85,8 +87,7 @@ public class ModbusMessagePersistListener implements BatchMessageListener { log.error("指令[{}]不存在,数据: {}", commandId, messageString); continue; } - this.redisTemplate.opsForValue() - .setIfAbsent(COMMAND_CACHE + commandId, JSONUtil.toJsonStr(commandMap), Duration.ofDays(1)); + this.redisTemplate.opsForValue().setIfAbsent(COMMAND_CACHE + commandId, JSONUtil.toJsonStr(commandMap), Duration.ofDays(1)); } try { String address; @@ -110,9 +111,9 @@ public class ModbusMessagePersistListener implements BatchMessageListener { case FunctionCode.READ_HOLDING_REGISTERS -> { values = ((ReadHoldingRegistersResponse) modbusResponse).getShortData(); } -// case FunctionCode.READ_EXCEPTION_STATUS -> { -// values = new short[]{((ReadExceptionStatusResponse) modbusResponse).getExceptionStatus()}; -// } + case FunctionCode.READ_EXCEPTION_STATUS -> { + values = new short[]{((ReadExceptionStatusResponse) modbusResponse).getExceptionStatus()}; + } default -> { throw new RuntimeException("Funcetion code not supported: " + modbusResponse.getFunctionCode()); } @@ -168,11 +169,11 @@ public class ModbusMessagePersistListener implements BatchMessageListener { String deviceDataCacheName = PersistenceHandler.DEVICE_DATA_CACHE + modbusMessage.getDeviceId(); HashOperations hashOperations = this.redisTemplate.opsForHash(); hashOperations.put(deviceDataCacheName, "deviceId", String.valueOf(modbusMessage.getDeviceId())); - hashOperations.put(deviceDataCacheName, "receiveTime", LocalDateTime.ofInstant(Instant - .ofEpochMilli(modbusMessage.getReceiveTime()), ZoneOffset.systemDefault()) + hashOperations.put(deviceDataCacheName, "receiveTime", LocalDateTime + .ofInstant(Instant.ofEpochMilli(modbusMessage.getReceiveTime()), ZoneOffset.systemDefault()) .format(LocalDateTimeDecodeHandler.OUT_FORMATTER)); - hashOperations.put(deviceDataCacheName, "collectionTime", LocalDateTime.ofInstant(Instant - .ofEpochMilli(modbusMessage.getCollectionTime()), ZoneOffset.systemDefault()) + hashOperations.put(deviceDataCacheName, "collectionTime", LocalDateTime + .ofInstant(Instant.ofEpochMilli(modbusMessage.getCollectionTime()), ZoneOffset.systemDefault()) .format(LocalDateTimeDecodeHandler.OUT_FORMATTER)); for (Map point : commandPointList) { fieldName = MapUtil.getStr(point, "field"); @@ -180,13 +181,17 @@ public class ModbusMessagePersistListener implements BatchMessageListener { decodeName = MapUtil.getStr(point, "decode_name"); startAddress = MapUtil.getInt(point, "start_address"); String value; - if (stepSize <= 1) { + if (StringUtils.startsWith(decodeName, HighLowBinDecodeHandler.NAME)) { + value = decodeHighLowCommandPoint(modbusMessage.getMessagePointMap(), decodeName, point, startAddress); + } else if (StringUtils.startsWith(decodeName, HighLowBinDecodeHandler.NAME)) { + value = decodeHighLowStepCommandPoint(modbusMessage.getMessagePointMap(), decodeName, point, startAddress, stepSize); + } else if (stepSize <= 1) { messagePoint = modbusMessage.getMessagePointMap() .get(StringUtils.leftPad(String.valueOf(startAddress), 4, '0')); decodeMessage(decodeName, point, messagePoint); value = messagePoint.getValue(); } else { - value = decodeCommandPoint(modbusMessage.getMessagePointMap(), decodeName, point, startAddress, stepSize); + value = decodeStepCommandPoint(modbusMessage.getMessagePointMap(), decodeName, point, startAddress, stepSize); } hashOperations.put(deviceDataCacheName, fieldName, value); } @@ -194,15 +199,45 @@ public class ModbusMessagePersistListener implements BatchMessageListener { private void decodeMessage(String decodeName, Map commandPointMap, ModbusMessage.MessagePoint messagePoint) { if (StringUtils.isNotBlank(decodeName)) { - DecodeHandler decodeHandler = this.decodeHandlerMap.get(decodeName + "DecodeHandler"); + DecodeHandler decodeHandler; + if (StringUtils.contains(decodeName, ",")) { + decodeHandler = new ComposeDecodeHandler(Arrays.stream(StringUtils.split(decodeName, ",")) + .map(name -> this.decodeHandlerMap.get(name + DecodeHandler.DECODE_NAME)).filter(Objects::nonNull).toList()); + } else { + decodeHandler = this.decodeHandlerMap.get(decodeName + DecodeHandler.DECODE_NAME); + } if (Objects.nonNull(decodeHandler)) { decodeHandler.decode(commandPointMap, messagePoint); } } } - private String decodeCommandPoint(Map pointMap, String decodeName, - Map commandPointMap, int startAddress, int stepSize) { + private String decodeMessage(String decodeName, Map commandPointMap, String value) { + if (StringUtils.isNotBlank(decodeName)) { + DecodeHandler decodeHandler; + if (StringUtils.contains(decodeName, ",")) { + List handlers = Arrays.stream(StringUtils.split(decodeName, ",")) + .filter(name -> !StringUtils.equals(name, HighLowBinDecodeHandler.NAME)) + .map(name -> this.decodeHandlerMap.get(name + DecodeHandler.DECODE_NAME)) + .filter(Objects::nonNull) + .toList(); + if (handlers.size() == 1) { + decodeHandler = handlers.get(0); + } else { + decodeHandler = new ComposeDecodeHandler(handlers); + } + } else { + decodeHandler = this.decodeHandlerMap.get(decodeName + DecodeHandler.DECODE_NAME); + } + if (Objects.nonNull(decodeHandler)) { + return decodeHandler.decode(commandPointMap, value); + } + } + return value; + } + + private String decodeStepCommandPoint(Map pointMap, String decodeName, + Map commandPointMap, int startAddress, int stepSize) { String[] values = new String[stepSize]; ModbusMessage.MessagePoint messagePoint; for (int i = 0; i < stepSize; i++) { @@ -210,14 +245,37 @@ public class ModbusMessagePersistListener implements BatchMessageListener { values[i] = messagePoint.getValue(); } String format = MapUtil.getStr(commandPointMap, "format"); - String result = StringUtils.isBlank(format) ? StringUtils.join(values) : String.format(format, values); - if (StringUtils.isNotBlank(decodeName)) { - DecodeHandler decodeHandler = this.decodeHandlerMap.get(decodeName + "DecodeHandler"); - if (Objects.nonNull(decodeHandler)) { - return decodeHandler.decode(commandPointMap, result); - } - } - return result; + return decodeMessage(decodeName, commandPointMap, + StringUtils.isBlank(format) ? StringUtils.join(values) : String.format(format, values)); } + private String decodeHighLowCommandPoint(Map pointMap, String decodeName, + Map commandPointMap, int startAddress) { + String[] values = new String[2]; + ModbusMessage.MessagePoint messagePoint; + for (int i = 0; i < 2; i++) { + messagePoint = pointMap.get(StringUtils.leftPad(String.valueOf(startAddress + i), 4, '0')); + values[i] = messagePoint.getValue(); + } + String result = highLowBinDecodeHandler.decode(commandPointMap, StringUtils.join(values)); + return decodeMessage(decodeName, commandPointMap, result); + } + + private String decodeHighLowStepCommandPoint(Map pointMap, String decodeName, + Map commandPointMap, int startAddress, int stepSize) { + String[] values = new String[stepSize]; + ModbusMessage.MessagePoint highPoint; + ModbusMessage.MessagePoint lowPoint; + for (int i = 0; i < stepSize; i = i + 2) { + highPoint = pointMap.get(StringUtils.leftPad(String.valueOf(startAddress + i), 4, '0')); + lowPoint = pointMap.get(StringUtils.leftPad(String.valueOf(startAddress + i + 1), 4, '0')); + values[i] = highLowBinDecodeHandler.decode(commandPointMap, highPoint.getValue() + lowPoint.getValue()); + } + + String format = MapUtil.getStr(commandPointMap, "format"); + return decodeMessage(decodeName, commandPointMap, + StringUtils.isBlank(format) ? StringUtils.join(values) : String.format(format, values)); + } + + } diff --git a/src/main/java/com/isu/gaswellwatch/utils/ReverseComplementCodeUtils.java b/src/main/java/com/isu/gaswellwatch/utils/ReverseComplementCodeUtils.java new file mode 100644 index 0000000..7f99a71 --- /dev/null +++ b/src/main/java/com/isu/gaswellwatch/utils/ReverseComplementCodeUtils.java @@ -0,0 +1,102 @@ +package com.isu.gaswellwatch.utils; + +/** + * @author 王仕龙 + * 2024/11/25 16:07 + */ +public class ReverseComplementCodeUtils { + + /** + * 原码转反码 + * + * @param source 二进制原码 + * @return + */ + public static String binOriginalToReverse(String source) { + if (source.startsWith("0")) { + return source; + } else { + StringBuffer sbf = new StringBuffer(); + sbf.append("1"); + String f_str = source.substring(1); + for (int i = 0; i < f_str.length(); i++) { + String s_str = String.valueOf(f_str.charAt(i)); + if (s_str.equals("0")) { + sbf.append("1"); + } else if (s_str.equals("1")) { + sbf.append("0"); + } + } + return sbf.toString(); + } + } + + /** + * 反码转补码, 默认补1 + * + * @param reverse 二进制反码字符串 + * @return + */ + public static String binReverseToComplement(String reverse) { + return binReverseToComplement(reverse, "1"); + } + + /** + * 反码转补码 + * + * @param reverse 二进制反码字符串 + * @param complement 二进制补数字符串 + * @return + */ + public static String binReverseToComplement(String reverse, String complement) { + if (reverse.startsWith("0")) { + return reverse; + } + StringBuilder sb = new StringBuilder(); + int x = 0; + int y = 0; + int pre = 0;//进位 + int sum = 0;//存储进位和另两个位的和 + while (reverse.length() != complement.length()) {//将两个二进制的数位数补齐,在短的前面添0 + if (reverse.length() > complement.length()) { + complement = "0" + complement; + } else { + reverse = "0" + reverse; + } + } + for (int i = reverse.length() - 1; i >= 0; i--) { + x = reverse.charAt(i) - '0'; + y = complement.charAt(i) - '0'; + sum = x + y + pre;//从低位做加法 + if (sum >= 2) { + pre = 1;//进位 + sb.append(sum - 2); + } else { + pre = 0; + sb.append(sum); + } + } + if (pre == 1) { + sb.append("1"); + } + // 翻转返回 + return sb.reverse().toString(); + } + + /** + * 补码转十进制 + * + * @param + * @return + */ + + public static String binComplementToDec(String complement) { + String h_number = complement.substring(1); + if (complement.startsWith("0")) { + return "" + Long.valueOf(h_number, 2); + } else if (complement.startsWith("1")) { + return "-" + Long.valueOf(h_number, 2); + } + return null; + } +}