Browse Source

1、采用工厂+策略改造指令生成以及解析

dev
mh 7 days ago
parent
commit
f48279969a
  1. 13
      2024新增脚本.sql
  2. 45
      common/pom.xml
  3. 12
      common/src/main/java/com/mh/common/page/PageRequest.java
  4. 12
      user-service/pom.xml
  5. 13
      user-service/src/main/java/com/mh/user/constants/Constant.java
  6. 60
      user-service/src/main/java/com/mh/user/constants/ProtocolEnum.java
  7. 60
      user-service/src/main/java/com/mh/user/constants/ProtocolStrategyEnum.java
  8. 41
      user-service/src/main/java/com/mh/user/controller/ChillersController.java
  9. 2
      user-service/src/main/java/com/mh/user/controller/DevicesManageController.java
  10. 2
      user-service/src/main/java/com/mh/user/controller/DevicesParamsController.java
  11. 2
      user-service/src/main/java/com/mh/user/controller/GatewayManageController.java
  12. 2
      user-service/src/main/java/com/mh/user/controller/MeterManageController.java
  13. 2
      user-service/src/main/java/com/mh/user/controller/ProjectInfoController.java
  14. 33
      user-service/src/main/java/com/mh/user/entity/DeviceCodeParamEntity.java
  15. 11
      user-service/src/main/java/com/mh/user/entity/DeviceManageEntity.java
  16. 9
      user-service/src/main/java/com/mh/user/entity/MeterManageEntity.java
  17. 48
      user-service/src/main/java/com/mh/user/factory/CJ188Protocol.java
  18. 48
      user-service/src/main/java/com/mh/user/factory/EleProtocol.java
  19. 47
      user-service/src/main/java/com/mh/user/factory/ModbusProtocol.java
  20. 36
      user-service/src/main/java/com/mh/user/factory/Protocol.java
  21. 17
      user-service/src/main/java/com/mh/user/factory/ProtocolFactory.java
  22. 138
      user-service/src/main/java/com/mh/user/job/CollectionLoopRunner.java
  23. 14
      user-service/src/main/java/com/mh/user/mapper/chillers/ChillersMapper.java
  24. 2
      user-service/src/main/java/com/mh/user/service/BaseService.java
  25. 4
      user-service/src/main/java/com/mh/user/service/MeterManageService.java
  26. 4
      user-service/src/main/java/com/mh/user/service/chillers/ChillersService.java
  27. 72
      user-service/src/main/java/com/mh/user/service/chillers/impl/ChillersServiceImpl.java
  28. 2
      user-service/src/main/java/com/mh/user/service/impl/DeviceParamsServiceImpl.java
  29. 2
      user-service/src/main/java/com/mh/user/service/impl/DevicesManageServiceImpl.java
  30. 2
      user-service/src/main/java/com/mh/user/service/impl/GatewayManageServiceImpl.java
  31. 28
      user-service/src/main/java/com/mh/user/service/impl/MeterManageServiceImpl.java
  32. 2
      user-service/src/main/java/com/mh/user/service/impl/ProjectInfoServiceImpl.java
  33. 87
      user-service/src/main/java/com/mh/user/strategy/CJ188ProtocolStrategy.java
  34. 121
      user-service/src/main/java/com/mh/user/strategy/EleProtocolStrategy.java
  35. 93
      user-service/src/main/java/com/mh/user/strategy/ModbusProtocolStrategy.java
  36. 28
      user-service/src/main/java/com/mh/user/strategy/ProtocolStrategy.java
  37. 17
      user-service/src/main/java/com/mh/user/strategy/ProtocolStrategyFactory.java
  38. 7
      user-service/src/main/resources/application-dev.yml
  39. 5
      user-service/src/main/resources/application-prod.yml
  40. 5
      user-service/src/main/resources/application-test.yml
  41. 19
      user-service/src/test/java/com/mh/user/socket/NIOServer.java

13
2024新增脚本.sql

@ -221,3 +221,16 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'校验位', @l
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'备注', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'device_params', @level2type=N'Column', @level2name=N'remark';
-- 2024-08-22
-- 2028-09-02
ALTER TABLE devices_manage ADD factory_barcode varchar(100) NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'出厂条码', 'schema', N'dbo', 'table', N'devices_manage', 'column', N'factory_barcode';
ALTER TABLE devices_manage ADD imu_code varchar(100) NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'IMU编码', 'schema', N'dbo', 'table', N'devices_manage', 'column', N'imu_code';
ALTER TABLE meter_manage ADD register_size int DEFAULT 1 NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'寄存器大小', 'schema', N'dbo', 'table', N'meter_manage', 'column', N'register_size';
ALTER TABLE meter_manage ADD is_use bit DEFAULT 1 NULL;
EXEC sys.sp_addextendedproperty 'MS_Description', N'当前采集点位是否启用', 'schema', N'dbo', 'table', N'meter_manage', 'column', N'is_use';

45
common/pom.xml

@ -31,27 +31,40 @@
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>6.1.0</version>
<exclusions>
<exclusion>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>sqlparser4.5</artifactId>
<version>6.1.0</version>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>sqlparser-timeout</artifactId>
<version>6.1.0</version>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.pagehelper</groupId>-->
<!-- <artifactId>pagehelper</artifactId>-->
<!-- <version>6.1.0</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>com.github.jsqlparser</groupId>-->
<!-- <artifactId>jsqlparser</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.github.pagehelper</groupId>-->
<!-- <artifactId>sqlparser4.5</artifactId>-->
<!-- <version>6.1.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.github.pagehelper</groupId>-->
<!-- <artifactId>sqlparser-timeout</artifactId>-->
<!-- <version>6.1.0</version>-->
<!-- </dependency>-->
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>

12
common/src/main/java/com/mh/common/page/PageRequest.java

@ -20,7 +20,7 @@ public class PageRequest {
/**
* 每页数量
*/
private Map<String, ColumnFilter> columnFilters = new HashMap<String, ColumnFilter>();
private Map<String, ColumnFilter> columnFilter = new HashMap<String, ColumnFilter>();
public int getPageNum() {
return pageNum;
@ -34,13 +34,13 @@ public class PageRequest {
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public Map<String, ColumnFilter> getColumnFilters() {
return columnFilters;
public Map<String, ColumnFilter> getColumnFilter() {
return columnFilter;
}
public void setColumnFilters(Map<String, ColumnFilter> columnFilters) {
this.columnFilters = columnFilters;
public void setColumnFilter(Map<String, ColumnFilter> columnFilters) {
this.columnFilter = columnFilters;
}
public ColumnFilter getColumnFilter(String name) {
return columnFilters.get(name);
return columnFilter.get(name);
}
}

12
user-service/pom.xml

@ -86,18 +86,6 @@
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>3.0.2</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
<exclusions>
<exclusion>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- mysql数据库链接-->
<!-- <dependency>-->
<!-- <groupId>mysql</groupId>-->

13
user-service/src/main/java/com/mh/user/constants/Constant.java

@ -9,10 +9,21 @@ package com.mh.user.constants;
*/
public class Constant {
public static boolean CONTROL_WEB_FLAG = false;
public static final String FAIL = "fail";
public static final String SUCCESS = "success";
public static boolean CONTROL_WEB_FLAG = false;
public static boolean SEND_STATUS = false; // 指令发送状态
public static boolean FLAG = false;
public static boolean WEB_FLAG = false; // 判断是否有前端指令下发
public static int projectId=1; // 项目编号
public static Long THREE_METER = 1L; // 三相电表
public static Long COOLING_METER = 2L; // 冷量计
public static Long DIG_DISPLAY_METER = 3L; // 数显电表
public static float CARBON_EMISSION_FACTOR = 0.6379f;
}

60
user-service/src/main/java/com/mh/user/constants/ProtocolEnum.java

@ -0,0 +1,60 @@
package com.mh.user.constants;
import com.mh.user.factory.CJ188Protocol;
import com.mh.user.factory.EleProtocol;
import com.mh.user.factory.ModbusProtocol;
import com.mh.user.factory.Protocol;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 协议枚举类
* @date 2024-09-12 10:31:53
*/
public enum ProtocolEnum {
CJ188_PROTOCOL("0", CJ188Protocol.getInstance()),
MODBUS_PROTOCOL("1", ModbusProtocol.getInstance()),
ELE_97_PROTOCOL("2", EleProtocol.getInstance()),
ELE_07_PROTOCOL("3", EleProtocol.getInstance()),
;
private String protocolType;
private Protocol protocol;
private ProtocolEnum(String protocolType, Protocol protocol) {
this.protocolType = protocolType;
this.protocol = protocol;
}
public String getProtocolType() {
return protocolType;
}
public void setProtocolType(String protocolType) {
this.protocolType = protocolType;
}
public Protocol getProtocol() {
return protocol;
}
public void setProtocol(Protocol protocol) {
this.protocol = protocol;
}
public static Protocol getProtocol(String protocolType) {
for (ProtocolEnum protocolEnum : ProtocolEnum.values()) {
if (protocolEnum.getProtocolType().equals(protocolType)) {
return protocolEnum.getProtocol();
}
}
return null;
}
}

60
user-service/src/main/java/com/mh/user/constants/ProtocolStrategyEnum.java

@ -0,0 +1,60 @@
package com.mh.user.constants;
import com.mh.user.strategy.CJ188ProtocolStrategy;
import com.mh.user.strategy.EleProtocolStrategy;
import com.mh.user.strategy.ModbusProtocolStrategy;
import com.mh.user.strategy.ProtocolStrategy;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 协议枚举类
* @date 2024-09-12 10:31:53
*/
public enum ProtocolStrategyEnum {
CJ188_PROTOCOL("0", CJ188ProtocolStrategy.getInstance()),
MODBUS_PROTOCOL("1", ModbusProtocolStrategy.getInstance()),
ELE_97_PROTOCOL("2", EleProtocolStrategy.getInstance()),
ELE_07_PROTOCOL("3", EleProtocolStrategy.getInstance()),
;
private String protocolType;
private ProtocolStrategy protocolStrategy;
ProtocolStrategyEnum(String protocolType, ProtocolStrategy protocolStrategy) {
this.protocolType = protocolType;
this.protocolStrategy = protocolStrategy;
}
public String getProtocolType() {
return protocolType;
}
public void setProtocolType(String protocolType) {
this.protocolType = protocolType;
}
public ProtocolStrategy getProtocolStrategy() {
return protocolStrategy;
}
public void setProtocolStrategy(ProtocolStrategy protocolStrategy) {
this.protocolStrategy = protocolStrategy;
}
public static ProtocolStrategy getProtocolStrategy(String protocolType) {
for (ProtocolStrategyEnum protocolStrategyEnum : ProtocolStrategyEnum.values()) {
if (protocolStrategyEnum.getProtocolType().equals(protocolType)) {
return protocolStrategyEnum.getProtocolStrategy();
}
}
return null;
}
}

41
user-service/src/main/java/com/mh/user/controller/ChillersController.java

@ -1,5 +1,6 @@
package com.mh.user.controller;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.mh.common.http.HttpResult;
@ -11,10 +12,7 @@ import com.mh.user.service.chillers.DeviceDisplayService;
import com.mh.user.service.chillers.GaugeService;
import com.mh.user.vo.HostListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -37,6 +35,12 @@ public class ChillersController {
this.deviceDisplayService = deviceDisplayService;
}
/**
* 查询主机列表详情信息
* @param proId
* @param systemId
* @return
*/
@GetMapping("/queryListByProId")
public HttpResult queryChillersByProId(@RequestParam(value = "proId", required = false) String proId,
@RequestParam("systemId") String systemId) {
@ -44,5 +48,34 @@ public class ChillersController {
return HttpResult.ok(resultJson);
}
/**
* 查询主机详情主页信息计算制冷量用电量碳排放平均COP等
* @param systemId
* @param proId
* @param deviceId
* @return
*/
@GetMapping("/queryHomeDetail/totalData")
public HttpResult totalData(@RequestParam("systemId") String systemId,
@RequestParam(value = "proId", required = false) String proId,
@RequestParam("deviceId") String deviceId) {
JSONObject resultJson = chillersService.queryTotalData(systemId, proId, deviceId);
return HttpResult.ok(resultJson);
}
/**
* 查询主机详情主页信息当日能耗分析
* @param systemId
* @param proId
* @param deviceId
* @return
*/
@GetMapping("/queryHomeDetail/chartData")
public HttpResult chartData(@RequestParam("systemId") String systemId,
@RequestParam(value = "proId", required = false) String proId,
@RequestParam("deviceId") String deviceId) {
JSONObject resultJson = chillersService.queryChartData(systemId, proId, deviceId);
return HttpResult.ok(resultJson);
}
}

2
user-service/src/main/java/com/mh/user/controller/DevicesManageController.java

@ -38,7 +38,7 @@ public class DevicesManageController {
@SysLogger(value="资产管理信息",optDesc = "根据项目id查询对应信息")
@GetMapping("/findById")
public HttpResult findById(@RequestParam("id") Integer id) {
public HttpResult findById(@RequestParam("id") Long id) {
DevicesManageEntity entity = devicesManageService.findById(id);
return HttpResult.ok(entity);
}

2
user-service/src/main/java/com/mh/user/controller/DevicesParamsController.java

@ -38,7 +38,7 @@ public class DevicesParamsController {
@SysLogger(value="资产管理信息",optDesc = "根据项目id查询对应信息")
@GetMapping("/findById")
public HttpResult findById(@RequestParam("id") Integer id) {
public HttpResult findById(@RequestParam("id") Long id) {
DeviceParamsEntity entity = deviceParamsService.findById(id);
return HttpResult.ok(entity);
}

2
user-service/src/main/java/com/mh/user/controller/GatewayManageController.java

@ -39,7 +39,7 @@ public class GatewayManageController {
@SysLogger(value="网关管理信息",optDesc = "根据项目id查询对应信息")
@GetMapping("/findById")
public HttpResult findById(@RequestParam("id") Integer id) {
public HttpResult findById(@RequestParam("id") Long id) {
GatewayManageEntity gatewayManageEntity = gatewayManageService.findById(id);
return HttpResult.ok(gatewayManageEntity);
}

2
user-service/src/main/java/com/mh/user/controller/MeterManageController.java

@ -38,7 +38,7 @@ public class MeterManageController {
@SysLogger(value="仪表管理信息",optDesc = "根据项目id查询对应信息")
@GetMapping("/findById")
public HttpResult findById(@RequestParam("id") Integer id) {
public HttpResult findById(@RequestParam("id") Long id) {
MeterManageEntity entity = meterManageService.findById(id);
return HttpResult.ok(entity);
}

2
user-service/src/main/java/com/mh/user/controller/ProjectInfoController.java

@ -41,7 +41,7 @@ public class ProjectInfoController {
@SysLogger(value="项目信息",optDesc = "根据项目id查询对应信息")
@GetMapping("/findById")
public HttpResult findById(@RequestParam("id") Integer id) {
public HttpResult findById(@RequestParam("id") Long id) {
ProjectInfoEntity projectInfoEntity = projectInfoService.findById(id);
return HttpResult.ok(projectInfoEntity);
}

33
user-service/src/main/java/com/mh/user/entity/DeviceCodeParamEntity.java

@ -11,7 +11,7 @@ import java.util.Date;
@Getter
@ToString
@TableName("device_code_param")
public class DeviceCodeParamEntity {
public class DeviceCodeParamEntity implements Cloneable {
private Long id;
private String deviceAddr;
@ -31,4 +31,35 @@ public class DeviceCodeParamEntity {
private Date createTime;
private String projectId;
/**
* 重置
*/
public void reset() {
this.deviceAddr = null;
this.deviceName = null;
this.deviceType = null;
this.strData = null;
this.dataPort = null;
this.baudRate = 0;
this.parity = null;
this.brand = null;
this.funCode = null;
this.registerAddr = null;
this.registerName = null;
this.digit = 0;
this.grade = 0;
this.dataValue = null;
this.createTime = null;
this.projectId = null;
}
@Override
public DeviceCodeParamEntity clone() {
try {
// TODO: copy mutable state here, so the clone can't change the internals of the original
return (DeviceCodeParamEntity) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}

11
user-service/src/main/java/com/mh/user/entity/DeviceManageEntity.java

@ -39,6 +39,17 @@ public class DeviceManageEntity extends BaseEntity {
private String createTimes;
private String updateTimes;
/**
* 出厂编码
*/
private String factoryBarcode;
/**
* imuCode
*/
private String imuCode;
@Override
public String toString() {
return "DeviceManageEntity{" +

9
user-service/src/main/java/com/mh/user/entity/MeterManageEntity.java

@ -161,7 +161,7 @@ public class MeterManageEntity implements Serializable {
/**
* 协议类型
*/
private Long protocolType;
private int protocolType;
/**
* 备注
@ -188,6 +188,11 @@ public class MeterManageEntity implements Serializable {
*/
private Long communicationType;
/**
* 读取寄存器大小
*/
private int registerSize;
@Override
public String toString() {
return "MeterManageEntity{" +
@ -223,6 +228,8 @@ public class MeterManageEntity implements Serializable {
", grade=" + grade +
", systemId=" + systemId +
", projectId=" + projectId +
", communicationType=" + communicationType +
", registerSize=" + registerSize +
'}';
}
}

48
user-service/src/main/java/com/mh/user/factory/CJ188Protocol.java

@ -0,0 +1,48 @@
package com.mh.user.factory;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.strategy.ProtocolStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 水表标准协议
* @date 2024-09-12 14:04:01
*/
@Slf4j
public class CJ188Protocol implements Protocol {
private ProtocolStrategy cj188ProtocolStrategy;
private static class SingletonHolder{
private static final CJ188Protocol INSTANCE = new CJ188Protocol();
}
private CJ188Protocol(){
// 防止外部直接实例化
}
public static CJ188Protocol getInstance(){
return SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(ProtocolStrategy protocolStrategy) {
this.cj188ProtocolStrategy = protocolStrategy;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("水表标准协议:工厂创建报文");
return cj188ProtocolStrategy.createOrder(meterManageEntity);
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("水表标准协议:工厂解析报文");
return cj188ProtocolStrategy.analysisReceiveData(meterManageEntity, receiveData);
}
}

48
user-service/src/main/java/com/mh/user/factory/EleProtocol.java

@ -0,0 +1,48 @@
package com.mh.user.factory;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.strategy.ProtocolStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 水表标准协议
* @date 2024-09-12 14:04:01
*/
@Slf4j
public class EleProtocol implements Protocol {
private ProtocolStrategy eleProtocolStrategy;
private static class SingletonHolder{
private static final EleProtocol INSTANCE = new EleProtocol();
}
private EleProtocol(){
// 防止外部直接实例化
}
public static EleProtocol getInstance(){
return SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(ProtocolStrategy protocolStrategy) {
this.eleProtocolStrategy = protocolStrategy;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("电表97/07规约协议:工厂创建报文");
return eleProtocolStrategy.createOrder(meterManageEntity);
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("电表97/07规约协议:工厂解析报文");
return eleProtocolStrategy.analysisReceiveData(meterManageEntity, receiveData);
}
}

47
user-service/src/main/java/com/mh/user/factory/ModbusProtocol.java

@ -0,0 +1,47 @@
package com.mh.user.factory;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.strategy.ProtocolStrategy;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description modbus协议
* @date 2024-09-12 16:38:44
*/
@Slf4j
public class ModbusProtocol implements Protocol {
private ProtocolStrategy modbusProtocolStrategy;
private static class SingletonHolder{
private static final ModbusProtocol INSTANCE = new ModbusProtocol();
}
private ModbusProtocol(){
// 防止外部直接实例化
}
public static ModbusProtocol getInstance(){
return ModbusProtocol.SingletonHolder.INSTANCE;
}
@Override
public void setStrategy(ProtocolStrategy protocolStrategy) {
this.modbusProtocolStrategy = protocolStrategy;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("modbus标准协议:工厂创建报文");
return modbusProtocolStrategy.createOrder(meterManageEntity);
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("modbus标准协议:工厂解析报文");
return modbusProtocolStrategy.analysisReceiveData(meterManageEntity, receiveData);
}
}

36
user-service/src/main/java/com/mh/user/factory/Protocol.java

@ -0,0 +1,36 @@
package com.mh.user.factory;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.strategy.ProtocolStrategy;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 根据协议实现对设备的生产和解析
* @date 2024-09-12 11:17:20
*/
public interface Protocol {
/**
* 设置协议策略
* @param protocolStrategy
*/
void setStrategy(ProtocolStrategy protocolStrategy);
/**
* 创建指令
* @param meterManageEntity
* @return
*/
String createOrder(MeterManageEntity meterManageEntity);
/**
* 解析指令
* @param meterManageEntity
* @param receiveData
* @return
*/
String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData);
}

17
user-service/src/main/java/com/mh/user/factory/ProtocolFactory.java

@ -0,0 +1,17 @@
package com.mh.user.factory;
import com.mh.user.constants.ProtocolEnum;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 协议工厂
* @date 2024-09-12 10:29:51
*/
public class ProtocolFactory {
public static Protocol matchProtocol(String protocolType) {
return ProtocolEnum.getProtocol(protocolType);
}
}

138
user-service/src/main/java/com/mh/user/job/CollectionLoopRunner.java

@ -1,8 +1,13 @@
package com.mh.user.job;
import com.mh.user.entity.ProjectInfoEntity;
import com.mh.common.page.PageRequest;
import com.mh.user.entity.*;
import com.mh.user.factory.Protocol;
import com.mh.user.factory.ProtocolFactory;
import com.mh.user.netty.EchoServer;
import com.mh.user.service.ProjectInfoService;
import com.mh.user.service.*;
import com.mh.user.strategy.ProtocolStrategy;
import com.mh.user.strategy.ProtocolStrategyFactory;
import com.mh.user.utils.GetReadOrder485;
import gnu.io.SerialPort;
import lombok.extern.slf4j.Slf4j;
@ -10,7 +15,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.*;
/**
* @author ljf
@ -23,25 +29,117 @@ import java.util.List;
@Component
public class CollectionLoopRunner implements ApplicationRunner {
public static SerialPort serialPort = null;
public static SerialPort serialPort = null;
@Autowired
ProjectInfoService projectInfoService;
@Autowired
ProjectInfoService projectInfoService;
@Override
public void run(ApplicationArguments args) throws Exception {
GetReadOrder485 getReadOrder485=new GetReadOrder485();
List<ProjectInfoEntity> projectInfoEntities = projectInfoService.queryProjectInfo("1");
if (null != projectInfoEntities && !projectInfoEntities.isEmpty()) {
for (ProjectInfoEntity projectInfoEntity : projectInfoEntities) {
getReadOrder485.createOrderParam(String.valueOf(projectInfoEntity.getId())); //生成采集参数,1新珠江(6000),2广合科技(6001),3广大科技(6002),6珠江国际,7保利山庄,8东莞迎宾馆
}
}
try{
new EchoServer(6001).start(); // 调用服务器的start方法,网关作为客户端,6006新珠江,6001广合科技,6077广大科技 6028(6006)珠江国际,5000保利山庄,6004东莞迎宾馆
}catch (Exception e){
log.info("6001端口已占用!");
@Autowired
private MeterManageService meterManageService;
@Autowired
private DeviceCodeParamService deviceCodeParamService;
@Autowired
private GatewayManageService gatewayManageService;
@Autowired
private DeviceParamsService deviceParamsService;
@Override
public void run(ApplicationArguments args) throws Exception {
List<ProjectInfoEntity> projectInfoEntities = projectInfoService.queryProjectInfo("1");
if (null != projectInfoEntities && !projectInfoEntities.isEmpty()) {
for (ProjectInfoEntity projectInfoEntity : projectInfoEntities) {
// getReadOrder485.createOrderParam(String.valueOf(projectInfoEntity.getId())); //生成采集参数,1新珠江(6000),2广合科技(6001),3广大科技(6002),6珠江国际,7保利山庄,8东莞迎宾馆
createOrderParamByStrategy(projectInfoEntity.getSystemId(), String.valueOf(projectInfoEntity.getId()));
}
}
try {
new EchoServer(6001).start(); // 调用服务器的start方法,网关作为客户端,6006新珠江,6001广合科技,6077广大科技 6028(6006)珠江国际,5000保利山庄,6004东莞迎宾馆
} catch (Exception e) {
log.info("6001端口已占用!");
}
}
public void createOrderParamByStrategy(String systemId, String projectId) throws InterruptedException {
int r;
if (projectId != null && !projectId.isEmpty()) {
r = deviceCodeParamService.queryCount(projectId);//查询记录数
} else {
r = deviceCodeParamService.queryCount2();//查询记录数
}
if (r > 0) {
return;
}
List<DeviceCodeParamEntity> deviceCodeParamEntityList = new ArrayList<>();
List<MeterManageEntity> meterManageEntities = Collections.emptyList();
if (projectId != null && !projectId.isEmpty()) {
meterManageEntities = meterManageService.queryBySystemIdAndProjectId(systemId, projectId);
}
DeviceCodeParamEntity deviceCodeParamEntity = new DeviceCodeParamEntity();
// 根据协议进行匹配生成采集报文
for (MeterManageEntity meterManageEntity : meterManageEntities) {
// 重置采集参数
deviceCodeParamEntity.reset();
// 创建设备报文
String protocolType = String.valueOf(meterManageEntity.getProtocolType());
Protocol protocol = ProtocolFactory.matchProtocol(protocolType);
ProtocolStrategy strategy = ProtocolStrategyFactory.matchProtocolStrategy(protocolType);
if (strategy == null) {
continue;
}
protocol.setStrategy(strategy);
String sendStr = protocol.createOrder(meterManageEntity);
log.info("采集指令===> {}", sendStr);
deviceCodeParamEntity.setDeviceAddr(meterManageEntity.getMtCode());
deviceCodeParamEntity.setDeviceName(meterManageEntity.getMtName());
deviceCodeParamEntity.setDeviceType(String.valueOf(meterManageEntity.getMtType()));
deviceCodeParamEntity.setStrData(sendStr);
try {
GatewayManageEntity gatewayManageEntity = gatewayManageService.findById(meterManageEntity.getGatewayId());
if (gatewayManageEntity != null) {
deviceCodeParamEntity.setDataPort(String.valueOf(gatewayManageEntity.getPort()));
}
} catch (Exception e) {
log.error("查询网关信息失败: {}", e.getMessage());
}
try {
DeviceParamsEntity paramsEntity = deviceParamsService.findById(meterManageEntity.getParamId());
if (paramsEntity != null) {
deviceCodeParamEntity.setBaudRate(paramsEntity.getBaudRate());
deviceCodeParamEntity.setParity(paramsEntity.getParity());
}
} catch (Exception e) {
log.error("查询设备参数失败: {}", e.getMessage());
}
deviceCodeParamEntity.setBrand(meterManageEntity.getMtBrand());
deviceCodeParamEntity.setFunCode(meterManageEntity.getFuncCode());
deviceCodeParamEntity.setRegisterAddr(meterManageEntity.getRegisterAddr());
deviceCodeParamEntity.setRegisterName(meterManageEntity.getOtherName());
deviceCodeParamEntity.setDigit(meterManageEntity.getDigits());
deviceCodeParamEntity.setGrade(meterManageEntity.getGrade());
deviceCodeParamEntity.setDataValue(null); // 传入值(目前不需要)
deviceCodeParamEntity.setProjectId(projectId);
deviceCodeParamEntity.setCreateTime(new Date());
deviceCodeParamEntityList.add(deviceCodeParamEntity.clone());
}
if (!deviceCodeParamEntityList.isEmpty()) {
deviceCodeParamService.insertDeviceCodeParamList(deviceCodeParamEntityList);
}
}
}
}

14
user-service/src/main/java/com/mh/user/mapper/chillers/ChillersMapper.java

@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* @author ljf
@ -181,4 +182,17 @@ public interface ChillersMapper {
@Result(column = "last_time", property = "lastTime")
})
List<ChillersEntity> getStopChillers();
@Select("select mt_type, cur_value, cur_time from meter_manage " +
" where system_id = #{systemId} and project_id = #{proId} and device_id = #{deviceId} " +
" and grade between 0 and 9 group by mt_type, cur_value, cur_time ")
List<Map<String, Object>> queryTotalData(@Param("systemId") String systemId,
@Param("proId") String proId,
@Param("deviceId") String deviceId);
@Select("select cur_date as curDate, elect, cl, cop, elect*#{carbonEmission} as carbonEmission from energy_data_mi where convert(varchar(10), getdate(), 120) = left(cur_date, 10) order by cur_date ")
List<Map<String, Object>> queryChartData(@Param("systemId") String systemId,
@Param("proId") String proId,
@Param("deviceId") String deviceId,
@Param("carbonEmission") float carbonEmission);
}

2
user-service/src/main/java/com/mh/user/service/BaseService.java

@ -16,7 +16,7 @@ public interface BaseService<T> {
void update(T entity);
T findById(Integer id);
T findById(Long id);
void save(T entity);

4
user-service/src/main/java/com/mh/user/service/MeterManageService.java

@ -2,6 +2,8 @@ package com.mh.user.service;
import com.mh.user.entity.MeterManageEntity;
import java.util.List;
/**
* @author LJF
* @version 1.0
@ -10,4 +12,6 @@ import com.mh.user.entity.MeterManageEntity;
* @date 2024-08-23 08:59:46
*/
public interface MeterManageService extends BaseService<MeterManageEntity> {
List<MeterManageEntity> queryBySystemIdAndProjectId(String systemId, String projectId);
}

4
user-service/src/main/java/com/mh/user/service/chillers/ChillersService.java

@ -61,4 +61,8 @@ public interface ChillersService {
List<String> queryDDCAddr(String ddcAddr);
JSONArray queryChillersByProId(String systemId, String proId);
JSONObject queryTotalData(String systemId, String proId, String deviceId);
JSONObject queryChartData(String systemId, String proId, String deviceId);
}

72
user-service/src/main/java/com/mh/user/service/chillers/impl/ChillersServiceImpl.java

@ -3,6 +3,7 @@ package com.mh.user.service.chillers.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mh.user.constants.Constant;
import com.mh.user.entity.*;
import com.mh.user.mapper.DevicesManageMapper;
import com.mh.user.mapper.MeterManageMapper;
@ -15,9 +16,11 @@ import com.mh.user.vo.HostListVO;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -329,7 +332,7 @@ public class ChillersServiceImpl implements ChillersService {
// 根据key(projectId)获取对应的项目名称
String projectName = projectInfoMapper.selectById(entry.getKey()).getProjectName();
JSONObject proJson = new JSONObject();
proJson.put("name", projectName);
proJson.put("name", projectName);
proJson.put("value", entry.getKey());
JSONArray children = new JSONArray();
@ -438,4 +441,71 @@ public class ChillersServiceImpl implements ChillersService {
}
}
@Override
public JSONObject queryTotalData(String systemId, String proId, String deviceId) {
JSONObject resultJson = new JSONObject();
List<Map<String, Object>> resultMap = chillersMapper.queryTotalData(systemId, proId, deviceId);
if (resultMap != null && !resultMap.isEmpty()) {
for (Map<String, Object> map : resultMap) {
Long mtType = (Long) map.get("mt_type");
if (Objects.equals(mtType, Constant.COOLING_METER)) {
// 冷量计
resultJson.put("coolingUsed", new BigDecimal(String.valueOf(map.get("cur_value"))).setScale(1, RoundingMode.HALF_UP));
} else if (Objects.equals(mtType, Constant.DIG_DISPLAY_METER) || Objects.equals(mtType, Constant.THREE_METER)) {
// 电量
resultJson.put("eleUsed", new BigDecimal(String.valueOf(map.get("cur_value"))).setScale(1, RoundingMode.HALF_UP));
}
}
if (resultJson.get("eleUsed") == null) {
resultJson.put("eleUsed", 0.0);
}
if (resultJson.get("coolingUsed") == null) {
resultJson.put("coolingUsed", 0.0);
}
resultJson.put("carbonEmission",
resultJson.getString("eleUsed").isEmpty() ? 0.0
: new BigDecimal(Constant.CARBON_EMISSION_FACTOR * Double.parseDouble(resultJson.getString("eleUsed")))
.setScale(1, RoundingMode.HALF_UP)
.doubleValue());
BigDecimal coolingUsed = resultJson.getBigDecimal("coolingUsed") == null ? BigDecimal.ZERO : resultJson.getBigDecimal("coolingUsed");
BigDecimal ele = resultJson.getBigDecimal("eleUsed") == null ? BigDecimal.ZERO : resultJson.getBigDecimal("eleUsed");
if (coolingUsed.compareTo(BigDecimal.ZERO) > 0
&& ele.compareTo(BigDecimal.ZERO) > 0) {
resultJson.put("coolingUsed", coolingUsed
.divide(new BigDecimal(String.valueOf(resultJson.getBigDecimal("eleUsed"))), 1, RoundingMode.HALF_UP));
} else if (ele.compareTo(BigDecimal.ZERO) == 0) {
resultJson.put("cop", 0.0);
}
return resultJson;
}
return resultJson;
}
@Override
public JSONObject queryChartData(String systemId, String proId, String deviceId) {
JSONObject resultJson = new JSONObject();
List<Map<String, Object>> resultList = chillersMapper.queryChartData(systemId, proId, deviceId, Constant.CARBON_EMISSION_FACTOR);
// 将 resultList 转换为包含时间戳和 COP 的字符串数组
String[] curDate = resultList.stream()
.map(map -> (String) map.get("curDate"))
.toArray(String[]::new);
BigDecimal[] elect = resultList.stream()
.map(map -> new BigDecimal(String.valueOf(map.get("elect"))))
.toArray(BigDecimal[]::new);
BigDecimal[] carbonEmission = resultList.stream()
.map(map -> new BigDecimal(String.valueOf(map.get("carbonEmission"))))
.toArray(BigDecimal[]::new);
BigDecimal[] cl = resultList.stream()
.map(map -> new BigDecimal(String.valueOf(map.get("cl"))))
.toArray(BigDecimal[]::new);
BigDecimal[] cop = resultList.stream()
.map(map -> new BigDecimal(String.valueOf(map.get("cop"))))
.toArray(BigDecimal[]::new);
resultJson.put("curDate", curDate);
resultJson.put("elect", elect);
resultJson.put("cl", cl);
resultJson.put("cop", cop);
resultJson.put("carbonEmission", carbonEmission);
return resultJson;
}
}

2
user-service/src/main/java/com/mh/user/service/impl/DeviceParamsServiceImpl.java

@ -52,7 +52,7 @@ public class DeviceParamsServiceImpl implements DeviceParamsService {
}
@Override
public DeviceParamsEntity findById(Integer id) {
public DeviceParamsEntity findById(Long id) {
return deviceParamsMapper.selectById(id);
}

2
user-service/src/main/java/com/mh/user/service/impl/DevicesManageServiceImpl.java

@ -58,7 +58,7 @@ public class DevicesManageServiceImpl implements DevicesManageService {
}
@Override
public DevicesManageEntity findById(Integer id) {
public DevicesManageEntity findById(Long id) {
return devicesManageMapper.selectById(id);
}

2
user-service/src/main/java/com/mh/user/service/impl/GatewayManageServiceImpl.java

@ -54,7 +54,7 @@ public class GatewayManageServiceImpl implements GatewayManageService {
}
@Override
public GatewayManageEntity findById(Integer id) {
public GatewayManageEntity findById(Long id) {
return gatewayManageMapper.selectById(id);
}

28
user-service/src/main/java/com/mh/user/service/impl/MeterManageServiceImpl.java

@ -11,9 +11,11 @@ import com.mh.user.entity.DevicesManageEntity;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.mapper.MeterManageMapper;
import com.mh.user.service.MeterManageService;
import com.mh.user.utils.ExchangeStringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -30,6 +32,19 @@ public class MeterManageServiceImpl implements MeterManageService {
@Autowired
private MeterManageMapper meterManageMapper;
@Override
public List<MeterManageEntity> queryBySystemIdAndProjectId(String systemId, String projectId) {
QueryWrapper<MeterManageEntity> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isBlank(systemId)) {
queryWrapper.eq("system_id", systemId);
}
if (!StringUtils.isBlank(projectId)) {
queryWrapper.eq("project_id", projectId);
}
queryWrapper.eq("is_use", 1);
return meterManageMapper.selectList(queryWrapper.orderByDesc("create_time"));
}
@Override
public PageResult queryByPage(PageRequest pageRequest) {
String systemID = StringUtils.getColumnFilterValue(pageRequest, "systemId");
@ -54,17 +69,28 @@ public class MeterManageServiceImpl implements MeterManageService {
@Override
public void update(MeterManageEntity entity) {
entity.setUpdateTime(new Date());
entity.setFuncCode(ExchangeStringUtil.addZeroForNum(entity.getFuncCode(), 2));
// 判断仪表类型:
// 电表格式化成12位
if (entity.getMtType() == 1) {
entity.setMtCode(ExchangeStringUtil.addZeroForNum(entity.getMtCode(), 12));
}
meterManageMapper.updateById(entity);
}
@Override
public MeterManageEntity findById(Integer id) {
public MeterManageEntity findById(Long id) {
return meterManageMapper.selectById(id);
}
@Override
public void save(MeterManageEntity entity) {
entity.setCreateTime(new Date());
entity.setFuncCode(ExchangeStringUtil.addZeroForNum(entity.getFuncCode(), 2));
// 电表格式化成12位
if (entity.getMtType() == 1) {
entity.setMtCode(ExchangeStringUtil.addZeroForNum(entity.getMtCode(), 12));
}
meterManageMapper.insert(entity);
}

2
user-service/src/main/java/com/mh/user/service/impl/ProjectInfoServiceImpl.java

@ -76,7 +76,7 @@ public class ProjectInfoServiceImpl implements ProjectInfoService {
}
@Override
public ProjectInfoEntity findById(Integer id) {
public ProjectInfoEntity findById(Long id) {
return projectInfoMapper.selectById(id);
}
}

87
user-service/src/main/java/com/mh/user/strategy/CJ188ProtocolStrategy.java

@ -0,0 +1,87 @@
package com.mh.user.strategy;
import com.mh.common.utils.StringUtils;
import com.mh.user.constants.Constant;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.factory.Protocol;
import com.mh.user.utils.ExchangeStringUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 水表标准协议
* @date 2024-09-12 14:04:01
*/
@Slf4j
public class CJ188ProtocolStrategy implements ProtocolStrategy {
private static class SingletonHolder{
private static final CJ188ProtocolStrategy INSTANCE = new CJ188ProtocolStrategy();
}
private CJ188ProtocolStrategy(){
// 防止外部直接实例化
}
public static CJ188ProtocolStrategy getInstance(){
return SingletonHolder.INSTANCE;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("水表标准协议:策略创建报文");
if (StringUtils.isBlank(meterManageEntity.getRegisterAddr())) {
return Constant.FAIL;
}
// 0 代表前面补充0,14 代表长度为14,d 代表参数为正数型
String str = String.format("%014d", Long.parseLong(meterManageEntity.getRegisterAddr()));//基表通讯号
// 转换位置
str = ExchangeStringUtil.changePosition(str);
// 拼接功能码
str = "6810" + str +
ExchangeStringUtil.addZeroForNum(meterManageEntity.getFuncCode(), 2)
+ "03" // 控制码
+ meterManageEntity.getIdentifyCode() // 水表读读数数据标识
+ "00"; // 序列号
// 检验和
String checkSum = ExchangeStringUtil.makeChecksum(str);
str = "FEFEFE" + str + checkSum + "16";
return str;
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("水表标准协议:策略解析报文");
String meterId = "";
String data = "";
if (receiveData.length() > 8) {
String str1 = receiveData.substring(0, 8);
String str2 = receiveData.substring(8);
receiveData = str1.replace("FE", "") + str2;
}
String checkStr = receiveData.substring(0, receiveData.length() - 4);//减去校验码
String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码
if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) {
meterId = checkStr.substring(16, 18) + checkStr.substring(14, 16) + checkStr.substring(12, 14) + checkStr.substring(10, 12)// 表号
+ checkStr.substring(8, 10) + checkStr.substring(6, 8) + checkStr.substring(4, 6);
meterId = String.format("%014d", Long.parseLong(meterId));
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 4; i++) {
String data1 = checkStr.substring(36 - 2 * (i + 1), 36 - 2 * i);
stringBuilder.append(data1);
}
data = stringBuilder.toString();
// 0 代表前面补充0,4 代表长度为4,d 代表参数为正数型
data = String.format("%08d", Long.parseLong(data));
data = data.substring(0, 6) + "." + data.substring(6, 8);
} else {
log.info("水表报文检验失败: {}", receiveData);
return Constant.FAIL;
}
log.info("水表表号: {},水表读数:{}", meterId, data);
return data;
}
}

121
user-service/src/main/java/com/mh/user/strategy/EleProtocolStrategy.java

@ -0,0 +1,121 @@
package com.mh.user.strategy;
import com.mh.common.utils.StringUtils;
import com.mh.user.constants.Constant;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.factory.Protocol;
import com.mh.user.utils.ExchangeStringUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 水表标准协议
* @date 2024-09-12 14:04:01
*/
@Slf4j
public class EleProtocolStrategy implements ProtocolStrategy {
private static class SingletonHolder{
private static final EleProtocolStrategy INSTANCE = new EleProtocolStrategy();
}
private EleProtocolStrategy(){
// 防止外部直接实例化
}
public static EleProtocolStrategy getInstance(){
return SingletonHolder.INSTANCE;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("电表97/07规约协议:策略创建报文");
String str = "";
String deviceAddr = meterManageEntity.getMtCode();
if (deviceAddr != null && !deviceAddr.isEmpty()) {
try {
//0代表前面补充0,12代表长度为12,d代表参数为正数型,基表通讯号
str = String.format("%012d", Long.parseLong(deviceAddr));
//转换位置
str = ExchangeStringUtil.changePosition(str);
//拼接功能码
str = "68" + str + "68";
String strData = "";
// 判断是什么协议
switch (meterManageEntity.getProtocolType()) {
case 2:
// 97协议
str += ExchangeStringUtil.addZeroForNum(meterManageEntity.getFuncCode(), 2) + "02";
strData = ExchangeStringUtil.addZeroForNum(meterManageEntity.getIdentifyCode(), 4);
break;
case 3:
// 07协议
str += ExchangeStringUtil.addZeroForNum(meterManageEntity.getFuncCode(), 2) + "04";
strData = ExchangeStringUtil.addZeroForNum(meterManageEntity.getIdentifyCode(), 8);
break;
default:
break;
}
//加33操作
str = str + ExchangeStringUtil.addThree(strData);
//检验和
String checkSum = ExchangeStringUtil.makeChecksum(str);
str = "FEFEFE" + str + checkSum + "16";
} catch (Exception e) {
log.error("生成采集电表指令错误==>", e);
return Constant.FAIL;
}
}
log.info("生成采集电表指令==>表号:{},指令:{}", meterManageEntity.getMtCode(),str);
return str.toUpperCase();
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("电表97/07规约协议:工厂解析报文");
String data = "";
if (receiveData.length() > 8) {
String str1 = receiveData.substring(0, 8);
String str2 = receiveData.substring(8);
receiveData = str1.replace("FE", "") + str2;
}
if (receiveData.length() == 36 || receiveData.length() == 40 || receiveData.length() == 44 || receiveData.length() == 50) {
String checkStr = receiveData.substring(0, receiveData.length() - 4); //减去校验码
String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码
//返回的校验码与重新生成的校验码进行校验
if (checkNum.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4, receiveData.length() - 2))) {
//表号,12位
String meterId = checkStr.substring(12, 14) + checkStr.substring(10, 12) + checkStr.substring(8, 10)
+ checkStr.substring(6, 8) + checkStr.substring(4, 6) + checkStr.substring(2, 4);
meterId = String.format("%012d", Long.parseLong(meterId));
StringBuilder stringBuilder = new StringBuilder();
if (receiveData.length() == 36) {
for (int i = 0; i < 4; i++) {
String data1 = checkStr.substring(32 - 2 * (i + 1), 32 - 2 * i);
stringBuilder.append(data1);
}
} else {
for (int i = 0; i < 4; i++) {
String data1 = checkStr.substring(36 - 2 * (i + 1), 36 - 2 * i);
stringBuilder.append(data1);
}
}
data = stringBuilder.toString();
data = ExchangeStringUtil.cutThree(data);
// 0 代表前面补充0,4 代表长度为4,d 代表参数为正数型
data = String.format("%08d", Long.parseLong(data));
data = data.substring(0, 6) + "." + data.substring(6, 8);
log.info("电表表号:{},电表读数:{}", meterId, data);
} else {
log.info("电表报文检验失败: {}", receiveData);
}
}
if (!StringUtils.isBlank(data)) {
data = String.valueOf(Double.valueOf(data)); //00010.76,去除读数前面带0的情况
}
return data;
}
}

93
user-service/src/main/java/com/mh/user/strategy/ModbusProtocolStrategy.java

@ -0,0 +1,93 @@
package com.mh.user.strategy;
import com.mh.common.utils.StringUtils;
import com.mh.user.constants.Constant;
import com.mh.user.entity.MeterManageEntity;
import com.mh.user.utils.ExchangeStringUtil;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 水表标准协议
* @date 2024-09-12 14:04:01
*/
@Slf4j
public class ModbusProtocolStrategy implements ProtocolStrategy {
private static class SingletonHolder {
private static final ModbusProtocolStrategy INSTANCE = new ModbusProtocolStrategy();
}
private ModbusProtocolStrategy() {
// 防止外部直接实例化
}
public static ModbusProtocolStrategy getInstance() {
return SingletonHolder.INSTANCE;
}
@Override
public String createOrder(MeterManageEntity meterManageEntity) {
log.info("modbus标准协议:策略创建报文");
if (StringUtils.isBlank(meterManageEntity.getRegisterAddr())) {
return Constant.FAIL;
}
String str;
try {
// 地址(1) + 功能码(1) + 寄存器地址(2) + 数据域(2) + crc校验
str = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(meterManageEntity.getMtCode()), 2) // 设备地址
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(meterManageEntity.getFuncCode()), 2) // 功能码
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(meterManageEntity.getRegisterAddr()), 4) // 寄存器地址
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(meterManageEntity.getRegisterSize())), 4); // 读取寄存器个数
// 循环冗余校验
String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验
str = str + checkWord;
} catch (Exception e) {
log.error("modbus标准协议:策略创建报文异常", e);
return Constant.FAIL;
}
return str;
}
@Override
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) {
log.info("modbus标准协议:策略解析报文");
String checkStr = receiveData.substring(0, receiveData.length() - 4);//检验报文
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码
String sValue = null;
String rtData = Constant.FAIL;
if (!checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) {
log.info("Modbus报文检验失败: {}", receiveData);
return rtData;
}
// 开始解析: 地址+功能码+数据长度+数据域
// 截取数据长度
String dataLength = receiveData.substring(6, 8);
int dataLengthInt = Integer.parseInt(dataLength, 16);
// 截取数据域
String data = receiveData.substring(8, 8 + dataLengthInt * 2);
// 判断
switch (meterManageEntity.getDataType()) {
case 0:
// 16进制转十进制类型
sValue = ExchangeStringUtil.hexToDec(data);
// 保留位数
sValue = (new BigDecimal(sValue)).divide(new BigDecimal(String.valueOf(meterManageEntity.getDigits() * 10)), 2, RoundingMode.HALF_UP).toString();
break;
case 1:
// 十六进制字符串转IEEE754浮点型
sValue = String.valueOf(ExchangeStringUtil.hexToSingle(data));
break;
default:
break;
}
log.info("解析数据==>表号:{},寄存器地址:{},值:{}", meterManageEntity.getMtNum(), meterManageEntity.getRegisterAddr(), sValue);
return sValue;
}
}

28
user-service/src/main/java/com/mh/user/strategy/ProtocolStrategy.java

@ -0,0 +1,28 @@
package com.mh.user.strategy;
import com.mh.user.entity.MeterManageEntity;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 协议策略
* @date 2024-09-12 11:13:30
*/
public interface ProtocolStrategy {
/**
* 创建指令
* @param meterManageEntity
* @return
*/
String createOrder(MeterManageEntity meterManageEntity);
/**
* 解析指令
* @param meterManageEntity
* @param receiveData
* @return
*/
String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData);
}

17
user-service/src/main/java/com/mh/user/strategy/ProtocolStrategyFactory.java

@ -0,0 +1,17 @@
package com.mh.user.strategy;
import com.mh.user.constants.ProtocolStrategyEnum;
/**
* @author LJF
* @version 1.0
* @project mh_esi
* @description 协议工厂
* @date 2024-09-12 10:29:51
*/
public class ProtocolStrategyFactory {
public static ProtocolStrategy matchProtocolStrategy(String protocolType) {
return ProtocolStrategyEnum.getProtocolStrategy(protocolType);
}
}

7
user-service/src/main/resources/application-dev.yml

@ -99,6 +99,13 @@ mybatis-plus:
map-underscore-to-camel-case: true
type-aliases-package: com.mh.user.entity
pagehelper:
reasonable: true
support-methods-arguments: true
params: countSql

5
user-service/src/main/resources/application-prod.yml

@ -99,4 +99,7 @@ mybatis-plus:
map-underscore-to-camel-case: true
type-aliases-package: com.mh.user.entity
pagehelper:
reasonable: true
support-methods-arguments: true
params: countSql

5
user-service/src/main/resources/application-test.yml

@ -99,4 +99,7 @@ mybatis-plus:
map-underscore-to-camel-case: true
type-aliases-package: com.mh.user.entity
pagehelper:
reasonable: true
support-methods-arguments: true
params: countSql

19
user-service/src/test/java/com/mh/user/socket/NIOServer.java

@ -1,5 +1,6 @@
package com.mh.user.socket;
import com.mh.user.utils.ExchangeStringUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@ -29,14 +30,16 @@ public class NIOServer {
private static ArrayList<SocketChannel> channels = new ArrayList<>();
public static void main(String[] args) throws IOException {
log.info("test");
NIOServer nioServer = new NIOServer();
// 缓冲测试
// nioServer.BufferTest();
// 通道测试
// nioServer.ChannelTest();
// Selector单线程操作
nioServer.SelectorSingleTest();
String s = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(1)), 4);
log.info(s);
// log.info("test");
// NIOServer nioServer = new NIOServer();
// // 缓冲测试
//// nioServer.BufferTest();
// // 通道测试
//// nioServer.ChannelTest();
// // Selector单线程操作
// nioServer.SelectorSingleTest();
}
// 缓冲区使用

Loading…
Cancel
Save