41 changed files with 1085 additions and 84 deletions
			
			
		@ -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; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -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; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -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; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
} | 
				
			||||
@ -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); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue