From 32bebfb2865925eff4b63877f96ac76347698d44 Mon Sep 17 00:00:00 2001 From: 25604 Date: Wed, 7 Jan 2026 19:41:31 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81mqtt=E6=95=B0=E6=8D=AE=E5=A4=84?= =?UTF-8?q?=E7=90=86=E4=BF=AE=E5=A4=8D=EF=BC=9B=202=E3=80=81=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E7=83=AD=E6=B3=B5=E6=B8=A9=E5=BA=A6=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mh/user/config/MyJacksonConfig.java | 49 +++++++++++++++++++ .../mh/user/dto/HotWaterControlListVO.java | 2 + .../mapper/CollectionParamsManageMapper.java | 4 +- .../com/mh/user/mapper/DataResultMapper.java | 12 +++-- .../mh/user/mapper/DeviceInstallMapper.java | 5 +- .../com/mh/user/mapper/NowDataMapper.java | 2 +- .../user/model/MyBigDecimalDeserializer.java | 34 +++++++++++++ .../com/mh/user/model/SanShiFengDatas.java | 12 +++-- .../com/mh/user/model/SanShiFengReceiver.java | 19 ++++--- .../com/mh/user/model/SanShiFengStrDatas.java | 33 +++++++++++++ .../mh/user/service/DeviceInstallService.java | 2 +- .../CollectionParamsManageServiceImpl.java | 17 +++++++ .../service/impl/DataResultServiceImpl.java | 30 +++++++++--- .../impl/DeviceControlServiceImpl.java | 15 +++--- .../impl/DeviceInstallServiceImpl.java | 4 +- .../mqtt/config/MqttInboundConfig.java | 10 ++-- .../mqtt/service/impl/EventsServiceImpl.java | 48 +++++++++++++++--- .../mh/user/strategy/EleMeterStrategy.java | 21 +++++++- .../user/strategy/SystemParamsStrategy.java | 4 +- .../com/mh/user/utils/ExchangeStringUtil.java | 13 +++++ .../src/main/resources/application.yml | 2 +- 21 files changed, 281 insertions(+), 57 deletions(-) create mode 100644 user-service/src/main/java/com/mh/user/config/MyJacksonConfig.java create mode 100644 user-service/src/main/java/com/mh/user/model/MyBigDecimalDeserializer.java create mode 100644 user-service/src/main/java/com/mh/user/model/SanShiFengStrDatas.java diff --git a/user-service/src/main/java/com/mh/user/config/MyJacksonConfig.java b/user-service/src/main/java/com/mh/user/config/MyJacksonConfig.java new file mode 100644 index 0000000..3c448bc --- /dev/null +++ b/user-service/src/main/java/com/mh/user/config/MyJacksonConfig.java @@ -0,0 +1,49 @@ +package com.mh.user.config; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.mh.user.model.MyBigDecimalDeserializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; +import java.math.BigDecimal; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 避免使用科学计数算法 + * @date 2026-01-07 14:37:11 + */ +@Configuration +public class MyJacksonConfig { + + @Bean("customObjectMapper") + public ObjectMapper customObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + + // 注册 JavaTimeModule + mapper.registerModule(new JavaTimeModule()); + + // 启用 BigDecimal 作为普通格式输出(避免科学计数法) + mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); + + // 注册自定义反序列化器 + SimpleModule module = new SimpleModule(); + module.addDeserializer(BigDecimal.class, new MyBigDecimalDeserializer()); + mapper.registerModule(module); + + // 启用 BigDecimal 处理浮点数 + mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); + + return mapper; + } + +} diff --git a/user-service/src/main/java/com/mh/user/dto/HotWaterControlListVO.java b/user-service/src/main/java/com/mh/user/dto/HotWaterControlListVO.java index 543deb6..807ade8 100644 --- a/user-service/src/main/java/com/mh/user/dto/HotWaterControlListVO.java +++ b/user-service/src/main/java/com/mh/user/dto/HotWaterControlListVO.java @@ -44,6 +44,8 @@ public class HotWaterControlListVO { private int ctOrderNum; + private int digits; + public BigDecimal getCurValue() { return curValue; } diff --git a/user-service/src/main/java/com/mh/user/mapper/CollectionParamsManageMapper.java b/user-service/src/main/java/com/mh/user/mapper/CollectionParamsManageMapper.java index cbd6c27..1adffa0 100644 --- a/user-service/src/main/java/com/mh/user/mapper/CollectionParamsManageMapper.java +++ b/user-service/src/main/java/com/mh/user/mapper/CollectionParamsManageMapper.java @@ -161,9 +161,10 @@ public interface CollectionParamsManageMapper extends BaseMapper , cur_value = #{curValue} " + " , ratio = #{ratio} " + " , calc_value = #{calcValue} " + - " where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType}" + + " where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id = #{buildingId}" + "") void updateDataResult(DataResultEntity dataResultEntity); @@ -60,16 +60,18 @@ public interface DataResultMapper { //查询单条记录 @ResultMap("rs") - @Select("select * from data_result where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType} ") + @Select("select top 1 * from data_result where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id = #{buildingId} ") DataResultEntity selectDataResult(@Param("curDate") String curDate, @Param("deviceAddr") String deviceAddr, - @Param("deviceType") String deviceType); + @Param("deviceType") String deviceType, + @Param("buildingId") String buildingId); //查询是否存在记录 - @Select("select count(*) from data_result where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType} ") + @Select("select count(*) from data_result where cur_date=#{curDate} and device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id = #{buildingId} ") // @Select("select count(*) from data_result") int selectDataResultCount(@Param("curDate") String curDate, @Param("deviceAddr") String deviceAddr, - @Param("deviceType") String deviceType); + @Param("deviceType") String deviceType, + @Param("buildingId") String buildingId); } diff --git a/user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java b/user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java index 3138824..3a69243 100644 --- a/user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java +++ b/user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java @@ -305,11 +305,12 @@ public interface DeviceInstallMapper extends BaseMapper { @Param("buildingId") String buildingId); //更新基表初始值 - @Update("update device_install set init_value=#{initValue} where device_addr=#{deviceAddr} and device_type=#{deviceType} and building_id=#{buildingId} ") + @Update("update device_install set init_value=#{initValue} where id = #{id} ") void updateInitValue(@Param("deviceAddr") String deviceAddr, @Param("deviceType") String deviceType, @Param("buildingId") String buildingId, - @Param("initValue") String initValue); + @Param("initValue") String initValue, + @Param("id") Long id); //查询最后一次采集时间 @Select("select last_date from device_install where device_type=#{deviceType} and device_addr=#{deviceAddr} and building_id=#{buildingId}") diff --git a/user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java b/user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java index bbb3d2f..93e3cd5 100644 --- a/user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java +++ b/user-service/src/main/java/com/mh/user/mapper/NowDataMapper.java @@ -213,7 +213,7 @@ public interface NowDataMapper { //查询历史表记录(热泵) @ResultMap(value = "rs") - @Select("select * from history_data where cur_date=#{curDate} and building_id=#{buildingId} and pump_id=#{pumpId}") + @Select("select top 1 * from history_data where cur_date=#{curDate} and building_id=#{buildingId} and pump_id=#{pumpId} ") NowDataEntity selectHistoryData(@Param("curDate") String curDate,@Param("buildingId") String buildingId,@Param("pumpId") String pumpId); //判断历史表有没有记录(非热泵) diff --git a/user-service/src/main/java/com/mh/user/model/MyBigDecimalDeserializer.java b/user-service/src/main/java/com/mh/user/model/MyBigDecimalDeserializer.java new file mode 100644 index 0000000..e2909ea --- /dev/null +++ b/user-service/src/main/java/com/mh/user/model/MyBigDecimalDeserializer.java @@ -0,0 +1,34 @@ +package com.mh.user.model; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.math.BigDecimal; + +/** + * @author LJF + * @version 1.0 + * @project CHWS + * @description 格式化 + * @date 2026-01-07 14:20:36 + */ +public class MyBigDecimalDeserializer extends JsonDeserializer { + + @Override + public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.getValueAsString(); + if (value == null || value.trim().isEmpty()) { + return BigDecimal.ZERO; + } + + try { + // 直接使用字符串构造BigDecimal,能正确处理科学计数法 + return new BigDecimal(value); + } catch (NumberFormatException e) { + // 如果转换失败,返回0 + return BigDecimal.ZERO; + } + } +} diff --git a/user-service/src/main/java/com/mh/user/model/SanShiFengDatas.java b/user-service/src/main/java/com/mh/user/model/SanShiFengDatas.java index 9099fb5..dd8b9ca 100644 --- a/user-service/src/main/java/com/mh/user/model/SanShiFengDatas.java +++ b/user-service/src/main/java/com/mh/user/model/SanShiFengDatas.java @@ -1,7 +1,11 @@ package com.mh.user.model; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.Data; +import java.math.BigDecimal; + /** * @author LJF * @version 1.0 @@ -10,7 +14,7 @@ import lombok.Data; * @date 2025-01-22 14:47:25 */ @Data -public class SanShiFengDatas { +public class SanShiFengDatas { /** * 对应研华的标签值 @@ -20,8 +24,10 @@ public class SanShiFengDatas { /** * 上报值 */ - private T value; - + // 使用自定义反序列化器处理科学计数法 + @JsonDeserialize(using = MyBigDecimalDeserializer.class) + @JsonFormat(shape = JsonFormat.Shape.STRING) // 以字符串形式输出,避免科学计数法 + private BigDecimal value; // /** // * 质量值 // */ diff --git a/user-service/src/main/java/com/mh/user/model/SanShiFengReceiver.java b/user-service/src/main/java/com/mh/user/model/SanShiFengReceiver.java index bf9bad3..2670d23 100644 --- a/user-service/src/main/java/com/mh/user/model/SanShiFengReceiver.java +++ b/user-service/src/main/java/com/mh/user/model/SanShiFengReceiver.java @@ -10,11 +10,10 @@ import java.util.List; * @author LJF * @version 1.0 * @project EEMCS - * @description 研华网关发送接收数据 + * @description 三石峰网关发送接收数据 * @date 2025-01-22 14:43:15 */ @Data -@JsonIgnoreProperties(ignoreUnknown = true) public class SanShiFengReceiver { /** @@ -33,13 +32,13 @@ public class SanShiFengReceiver { private String time; - // 确保在 getDatas() 方法中正确处理泛型类型 - public List getDatas() { - // 如果是从 JSON 反序列化,使用 TypeReference - if (this.datas != null) { - return (List) this.datas; - } - return Collections.emptyList(); - } +// // 确保在 getDatas() 方法中正确处理泛型类型 +// public List getDatas() { +// // 如果是从 JSON 反序列化,使用 TypeReference +// if (this.datas != null) { +// return (List) this.datas; +// } +// return Collections.emptyList(); +// } } diff --git a/user-service/src/main/java/com/mh/user/model/SanShiFengStrDatas.java b/user-service/src/main/java/com/mh/user/model/SanShiFengStrDatas.java new file mode 100644 index 0000000..533f9e6 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/model/SanShiFengStrDatas.java @@ -0,0 +1,33 @@ +package com.mh.user.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author LJF + * @version 1.0 + * @project EEMCS + * @description 三石峰数据体 + * @date 2025-01-22 14:47:25 + */ +@Data +public class SanShiFengStrDatas { + + /** + * 对应研华的标签值 + */ + private String name; + + /** + * 上报值 + */ + // 使用自定义反序列化器处理科学计数法 + private String value; +// /** +// * 质量值 +// */ +// private T quality; + +} diff --git a/user-service/src/main/java/com/mh/user/service/DeviceInstallService.java b/user-service/src/main/java/com/mh/user/service/DeviceInstallService.java index 041c6b2..940fb53 100644 --- a/user-service/src/main/java/com/mh/user/service/DeviceInstallService.java +++ b/user-service/src/main/java/com/mh/user/service/DeviceInstallService.java @@ -156,7 +156,7 @@ public interface DeviceInstallService { void deletePump(String deviceAddr,String deviceType,String buildingId); //更新基表初始值 - void updateInitValue(String deviceAddr, String deviceType, String buildingId, String initValue); + void updateInitValue(String deviceAddr, String deviceType, String buildingId, String initValue, Long id); //查询最后一次采集时间 String selectLastDate(String deviceType,String deviceAddr,String buildingId); diff --git a/user-service/src/main/java/com/mh/user/service/impl/CollectionParamsManageServiceImpl.java b/user-service/src/main/java/com/mh/user/service/impl/CollectionParamsManageServiceImpl.java index d162bdd..7b756f2 100644 --- a/user-service/src/main/java/com/mh/user/service/impl/CollectionParamsManageServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/impl/CollectionParamsManageServiceImpl.java @@ -10,6 +10,7 @@ import com.mh.user.service.CollectionParamsManageService; import org.springframework.stereotype.Service; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; @@ -293,6 +294,10 @@ public class CollectionParamsManageServiceImpl implements CollectionParamsManage hotPumpVo.setStop(item.getCurValue().toString()); hotPumpVo.setStopId(item.getCpmId()); break; + case "7": + // 温度设定 + hotPumpVo.setSetTemp(item.getCurValue()); + hotPumpVo.setSetTempId(item.getCpmId()); default: break; } @@ -695,6 +700,18 @@ public class CollectionParamsManageServiceImpl implements CollectionParamsManage case "13": case "14": // 水电表读数 + // 获取保留小数位 + // 获取保留小数位 + int digits = item.getDigits(); + // 10的n次方 + BigDecimal power = BigDecimal.ONE.scaleByPowerOfTen(digits); + + BigDecimal originalValue = item.getCurValue(); + + // 将数值按指定小数位数格式化 + BigDecimal formattedValue = originalValue.divide(power, 2, RoundingMode.HALF_UP); + item.setCurValue(formattedValue); + meterVo.setTotalReading(item.getCurValue()); meterVo.setTotalReadingId(item.getCpmId()); meterVo.setCurrentTime(item.getCurTime()); diff --git a/user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java b/user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java index 81bbf19..5f9175a 100644 --- a/user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java @@ -33,9 +33,11 @@ public class DataResultServiceImpl implements DataResultService { private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.000"); + private static final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + @Override public void saveDataResult(DataResultEntity dataResultEntity) { - SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + double lastValue=0; double calcValue=0; double initValue=0; @@ -53,7 +55,10 @@ public class DataResultServiceImpl implements DataResultService { dataResultEntity.setCurDate(formattedDate); //从安装表获取设备信息 - DeviceInstallEntity deviceInstallEntity=deviceInstallMapper.selectDevice(dataResultEntity.getDeviceAddr(),dataResultEntity.getDeviceType(),dataResultEntity.getBuildingId()); + DeviceInstallEntity deviceInstallEntity=deviceInstallMapper.selectDevice( + dataResultEntity.getDeviceAddr(), + dataResultEntity.getDeviceType(), + dataResultEntity.getBuildingId()); double ratio=deviceInstallEntity.getRatio(); //倍率 initValue=deviceInstallEntity.getInitValue(); dayValue=deviceInstallEntity.getDayValue(); @@ -69,15 +74,21 @@ public class DataResultServiceImpl implements DataResultService { } dayValue=100; } - int r = dataResultMapper.selectDataResultCount(sdf1.format(dataResultEntity.getCurDate()), - dataResultEntity.getDeviceAddr(),dataResultEntity.getDeviceType()); + int r = dataResultMapper.selectDataResultCount( + sdf1.format(dataResultEntity.getCurDate()), + dataResultEntity.getDeviceAddr(), + dataResultEntity.getDeviceType(), + dataResultEntity.getBuildingId()); if (r==0){//插入记录 // 获取上一个抄表记录curValue,curDate // dataResultEntity.getCurDate()减去5分钟, Calendar calendar = Calendar.getInstance(); calendar.setTime(dataResultEntity.getCurDate()); calendar.add(Calendar.MINUTE, -5); - DataResultEntity lastData = dataResultMapper.selectDataResult(sdf1.format(calendar.getTime()),dataResultEntity.getDeviceAddr(),dataResultEntity.getDeviceType()); + DataResultEntity lastData = dataResultMapper.selectDataResult(sdf1.format(calendar.getTime()), + dataResultEntity.getDeviceAddr(), + dataResultEntity.getDeviceType(), + dataResultEntity.getBuildingId()); DataResultEntity data=new DataResultEntity(); data.setDeviceAddr(dataResultEntity.getDeviceAddr()); //通讯地址 data.setDeviceType(dataResultEntity.getDeviceType()); //设备类型 @@ -123,7 +134,10 @@ public class DataResultServiceImpl implements DataResultService { } }else {//修改记录的curValue、calcValue - DataResultEntity data2=dataResultMapper.selectDataResult(sdf1.format(dataResultEntity.getCurDate()),dataResultEntity.getDeviceAddr(),dataResultEntity.getDeviceType()); + DataResultEntity data2=dataResultMapper.selectDataResult(sdf1.format(dataResultEntity.getCurDate()), + dataResultEntity.getDeviceAddr(), + dataResultEntity.getDeviceType(), + dataResultEntity.getBuildingId()); lastValue=data2.getLastValue(); //安装基表上次读数 calcValue=dataResultEntity.getCurValue()-lastValue; //计算用量 String curDate=sdf1.format(dataResultEntity.getCurDate()); @@ -156,7 +170,9 @@ public class DataResultServiceImpl implements DataResultService { } if(initValue==0){//第一次采集的时候 deviceInstallMapper.updateLastValue(deviceInstallEntity.getId(),String.valueOf(dataResultEntity.getCurValue()),date); - deviceInstallMapper.updateInitValue(dataResultEntity.getDeviceAddr(),dataResultEntity.getDeviceType(),dataResultEntity.getBuildingId(),String.valueOf(curValue)); + deviceInstallMapper.updateInitValue(dataResultEntity.getDeviceAddr(), + dataResultEntity.getDeviceType(), + dataResultEntity.getBuildingId(),String.valueOf(dataResultEntity.getCurValue()), deviceInstallEntity.getId()); } }catch (Exception e){ //e.printStackTrace(); diff --git a/user-service/src/main/java/com/mh/user/service/impl/DeviceControlServiceImpl.java b/user-service/src/main/java/com/mh/user/service/impl/DeviceControlServiceImpl.java index dde0fd8..2c46d26 100644 --- a/user-service/src/main/java/com/mh/user/service/impl/DeviceControlServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/impl/DeviceControlServiceImpl.java @@ -6,10 +6,7 @@ import com.mh.common.utils.StringUtils; import com.mh.user.constants.Constant; import com.mh.user.entity.*; import com.mh.user.mapper.CollectionParamsManageMapper; -import com.mh.user.model.DeviceModel; -import com.mh.user.model.SanShiFengDatas; -import com.mh.user.model.SanShiFengReceiver; -import com.mh.user.model.SerialPortModel; +import com.mh.user.model.*; import com.mh.user.serialport.SerialPortSingle2; import com.mh.user.service.*; import com.mh.user.utils.DateUtil; @@ -72,9 +69,9 @@ public class DeviceControlServiceImpl implements DeviceControlService { @Override public String operationDevice(SerialPortModel params) { // 拼接发送的报文 - SanShiFengReceiver sendData = new SanShiFengReceiver<>(); + SanShiFengReceiver sendData = new SanShiFengReceiver<>(); try { - List advantechDatas = getAdvantechDatas(params); + List advantechDatas = getAdvantechDatas(params); if (null == advantechDatas) { return Constant.FAIL; } @@ -90,8 +87,8 @@ public class DeviceControlServiceImpl implements DeviceControlService { return JSONObject.toJSONString(sendData); } - public List getAdvantechDatas(SerialPortModel params) { - List advantechDatas = new ArrayList<>(); + public List getAdvantechDatas(SerialPortModel params) { + List advantechDatas = new ArrayList<>(); String dataValue = params.getDataValue(); // 获取报文类型 // 获取报文其他信息 @@ -104,7 +101,7 @@ public class DeviceControlServiceImpl implements DeviceControlService { return null; } // 发送报文 - SanShiFengDatas data = new SanShiFengDatas(); + SanShiFengStrDatas data = new SanShiFengStrDatas(); data.setName(otherName); data.setValue(dataValue); advantechDatas.add(data); diff --git a/user-service/src/main/java/com/mh/user/service/impl/DeviceInstallServiceImpl.java b/user-service/src/main/java/com/mh/user/service/impl/DeviceInstallServiceImpl.java index e46eac4..55fa02a 100644 --- a/user-service/src/main/java/com/mh/user/service/impl/DeviceInstallServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/impl/DeviceInstallServiceImpl.java @@ -444,8 +444,8 @@ public class DeviceInstallServiceImpl implements DeviceInstallService { } @Override - public void updateInitValue(String deviceAddr, String deviceType, String buildingId, String initValue) { - deviceInstallMapper.updateInitValue(deviceAddr, deviceType, buildingId, initValue); + public void updateInitValue(String deviceAddr, String deviceType, String buildingId, String initValue, Long id) { + deviceInstallMapper.updateInitValue(deviceAddr, deviceType, buildingId, initValue, id); } @Override diff --git a/user-service/src/main/java/com/mh/user/service/mqtt/config/MqttInboundConfig.java b/user-service/src/main/java/com/mh/user/service/mqtt/config/MqttInboundConfig.java index f10b92e..b64e24d 100644 --- a/user-service/src/main/java/com/mh/user/service/mqtt/config/MqttInboundConfig.java +++ b/user-service/src/main/java/com/mh/user/service/mqtt/config/MqttInboundConfig.java @@ -99,11 +99,11 @@ public class MqttInboundConfig { @ServiceActivator(inputChannel = ChannelName.DEFAULT_BOUND) public MessageHandler handler() { return message -> { -// log.info("The default channel does not handle messages." + -// "\nTopic: {}" + -// "\nPayload: {}", -// message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC), -// message.getPayload()); + log.info("The default channel does not handle messages." + + "\nTopic: {}" + + "\nPayload: {}", + message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC), + message.getPayload()); }; } diff --git a/user-service/src/main/java/com/mh/user/service/mqtt/service/impl/EventsServiceImpl.java b/user-service/src/main/java/com/mh/user/service/mqtt/service/impl/EventsServiceImpl.java index 8302095..6427f33 100644 --- a/user-service/src/main/java/com/mh/user/service/mqtt/service/impl/EventsServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/mqtt/service/impl/EventsServiceImpl.java @@ -1,6 +1,7 @@ package com.mh.user.service.mqtt.service.impl; import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.mh.common.utils.StringUtils; import com.mh.user.constants.ChannelName; @@ -20,6 +21,7 @@ import com.mh.user.strategy.DeviceStrategyFactory; import io.netty.util.CharsetUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.integration.annotation.ServiceActivator; import org.springframework.messaging.MessageHeaders; import org.springframework.stereotype.Service; @@ -42,6 +44,7 @@ import java.util.Objects; public class EventsServiceImpl implements IEventsService { @Autowired + @Qualifier("customObjectMapper") private ObjectMapper mapper; @Autowired @@ -86,8 +89,9 @@ public class EventsServiceImpl implements IEventsService { private void handleInboundData(byte[] receiver,String topic, String logMessage) { try { - SanShiFengReceiver datas = new SanShiFengReceiver(); - datas = mapper.readValue(receiver, SanShiFengReceiver.class); + // 使用 TypeReference 确保泛型信息被保留 + SanShiFengReceiver datas = mapper.readValue(receiver, + new TypeReference>() {}); log.info("主题:{},类型:{}: ,数据:{}", topic, logMessage, datas.toString()); // 开始遍历 数据 String sn = datas.getSn(); @@ -108,7 +112,15 @@ public class EventsServiceImpl implements IEventsService { log.warn("数据列表为空,SN: {}", sn); return; } - // 并行处理数据列表,避免阻塞 + // 先批量更新collectionParam + rawDataList.parallelStream().forEach(rawData -> { + try { + processDataUpdateCpmItem(rawData, sn, plcName, projectName, time, buildingId); + } catch (Exception e) { + log.error("处理单个数据项失败: {}", rawData, e); + } + }); + // 并行处理数据列表,主线程等待处理完 rawDataList.parallelStream().forEach(rawData -> { try { processDataItem(rawData, sn, plcName, projectName, time, buildingId); @@ -121,7 +133,7 @@ public class EventsServiceImpl implements IEventsService { } } - private void processDataItem(Object rawData, String sn, String plcName, String projectName, String time, String buildingId) { + private void processDataUpdateCpmItem(Object rawData, String sn, String plcName, String projectName, String time, String buildingId) { // 安全地转换对象 SanShiFengDatas data = convertDataItem(rawData); if (data == null) { @@ -129,7 +141,7 @@ public class EventsServiceImpl implements IEventsService { return; } // 不使用消息队列,查询属于哪种设备类型,然后通过策略进行数据解析 - log.info("设备SN:{},PLC名称:{},项目名称:{},时间:{},数据:{}", sn, plcName, projectName, time, data.toString()); + // log.info("设备SN:{},PLC名称:{},项目名称:{},时间:{},数据:{}", sn, plcName, projectName, time, data.toString()); // 获取点位参数名称 String name = data.getName(); // 获取点位值 @@ -141,6 +153,28 @@ public class EventsServiceImpl implements IEventsService { } // 直接更新collectionParamManage参数值 collectionParamManageService.updateCPMByOtherName(name, value, time, buildingId); + } + + private void processDataItem(Object rawData, String sn, String plcName, String projectName, String time, String buildingId) { + // 安全地转换对象 + SanShiFengDatas data = convertDataItem(rawData); + if (data == null) { + log.warn("数据转换失败,跳过处理"); + return; + } + // 不使用消息队列,查询属于哪种设备类型,然后通过策略进行数据解析 + // log.info("设备SN:{},PLC名称:{},项目名称:{},时间:{},数据:{}", sn, plcName, projectName, time, data.toString()); + // 获取点位参数名称 + String name = data.getName(); + // 获取点位值 + BigDecimal value = new BigDecimal(0); + try { + value = new BigDecimal(String.valueOf(data.getValue())); + } catch (Exception e) { + value = BigDecimal.ZERO; + } + // 直接更新collectionParamManage参数值 + //collectionParamManageService.updateCPMByOtherName(name, value, time, buildingId); // 查询device_install表,走之前的逻辑 CollectionParamsManageEntity collectionParamsManageEntity = collectionParamManageService.selectDeviceInstallByOtherName(name, buildingId); if (null != collectionParamsManageEntity && collectionParamsManageEntity.getDeviceInstallId() != null) { @@ -152,7 +186,7 @@ public class EventsServiceImpl implements IEventsService { DeviceStrategy strategy = DeviceStrategyFactory.createStrategy(deviceType); if (strategy != null) { device.setStrategy(strategy); - device.analysisMQTTReceiveData(time, deviceInstallEntity.getDeviceAddr(), String.valueOf(value), Constant.READ, deviceInstallEntity, collectionParamsManageEntity); + device.analysisMQTTReceiveData(time, deviceInstallEntity.getDeviceAddr(), value.toPlainString(), Constant.READ, deviceInstallEntity, collectionParamsManageEntity); } } } @@ -177,7 +211,7 @@ public class EventsServiceImpl implements IEventsService { } catch (Exception e) { log.error("数据转换异常", e); data.setName(getJsonValueAsString(rawData, "name")); - data.setValue("-1"); + data.setValue(new BigDecimal("-1")); } return data; } diff --git a/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java b/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java index 498858e..def5e07 100644 --- a/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java +++ b/user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java @@ -12,6 +12,8 @@ import com.mh.user.utils.SpringBeanUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.Date; /** @@ -158,14 +160,29 @@ public class EleMeterStrategy implements DeviceStrategy { public String analysisMQTTReceiveData(String dateStr, String registerAddr, String dataStr, String operateType, DeviceInstallEntity deviceInstallEntity, CollectionParamsManageEntity collectionParamsManageEntity) { String data = Constant.FAIL; - if (Integer.parseInt(dataStr) < 0) { + if ((new BigDecimal(dataStr)).compareTo(new BigDecimal(0)) < 0) { return data; } - log.info("电表表号:{},电表读数:{}", deviceInstallEntity.getDeviceAddr(), dataStr); // 考虑dataStr是否走大数或者走小数 + // 获取保留的小数位 + Integer digits = collectionParamsManageEntity.getDigits(); + Integer grade = collectionParamsManageEntity.getGrade(); + if (grade != 40) { + return data; + } + // dataStr保留小数位 + // 10的n次方 + BigDecimal power = BigDecimal.ONE.scaleByPowerOfTen(digits); + // dataStr判断是否是科学表示法,是则转换为普通表示法 + dataStr = ExchangeStringUtil.isScientificNotation(dataStr); + BigDecimal originalValue = new BigDecimal(dataStr); + // 将数值按指定小数位数格式化 + dataStr = originalValue.divide(power, 2, RoundingMode.HALF_UP).toString(); + if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>1000 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) { dataStr = String.valueOf(deviceInstallEntity.getLastValue()); } + log.info("电表表号:{},电表读数:{}", deviceInstallEntity.getDeviceAddr(), dataStr); try { DataResultEntity dataResultEntity = new DataResultEntity(); dataResultEntity.setDeviceAddr(deviceInstallEntity.getDeviceAddr());//通讯编号 diff --git a/user-service/src/main/java/com/mh/user/strategy/SystemParamsStrategy.java b/user-service/src/main/java/com/mh/user/strategy/SystemParamsStrategy.java index 8b034ba..443022f 100644 --- a/user-service/src/main/java/com/mh/user/strategy/SystemParamsStrategy.java +++ b/user-service/src/main/java/com/mh/user/strategy/SystemParamsStrategy.java @@ -13,6 +13,8 @@ import com.mh.user.utils.SpringBeanUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; +import java.math.BigDecimal; + /** * @author LJF * @version 1.0 @@ -61,7 +63,7 @@ public class SystemParamsStrategy implements DeviceStrategy { public String analysisMQTTReceiveData(String dateStr, String registerAddr, String dataStr, String operateType, DeviceInstallEntity deviceInstallEntity, CollectionParamsManageEntity collectionParamsManageEntity) { String result = Constant.FAIL; - if (Integer.parseInt(dataStr) < 0) { + if ((new BigDecimal(dataStr)).compareTo(new BigDecimal(0)) < 0) { log.info("系统参数报文检验失败: " + dataStr); return result; } diff --git a/user-service/src/main/java/com/mh/user/utils/ExchangeStringUtil.java b/user-service/src/main/java/com/mh/user/utils/ExchangeStringUtil.java index dbf4950..abe8290 100644 --- a/user-service/src/main/java/com/mh/user/utils/ExchangeStringUtil.java +++ b/user-service/src/main/java/com/mh/user/utils/ExchangeStringUtil.java @@ -6,6 +6,7 @@ import io.netty.buffer.Unpooled; //import io.netty.buffer.ByteBuf; //import io.netty.channel.ChannelHandlerContext; import java.io.*; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -1275,4 +1276,16 @@ public class ExchangeStringUtil { } + /** + * 判断是否为科学计数法,如果是则返回非科学计数法 + * @param dataStr + * @return + */ + public static String isScientificNotation(String dataStr) { + if (dataStr.contains("E")) { + BigDecimal bigDecimal = new BigDecimal(dataStr); + return bigDecimal.toPlainString(); + } + return dataStr; + } } diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index 5f109b8..081dc84 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: dev + active: prod mvc: pathmatch: matching-strategy: ant_path_matcher