You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							135 lines
						
					
					
						
							6.3 KiB
						
					
					
				
			
		
		
	
	
							135 lines
						
					
					
						
							6.3 KiB
						
					
					
				package com.mh.user.strategy; | 
						|
 | 
						|
import com.mh.common.utils.StringUtils; | 
						|
import com.mh.user.entity.DataResultEntity; | 
						|
import com.mh.user.entity.DeviceCodeParamEntity; | 
						|
import com.mh.user.service.DataResultService; | 
						|
import com.mh.user.utils.CRC16; | 
						|
import com.mh.user.utils.ExchangeStringUtil; | 
						|
import com.mh.user.utils.SpringBeanUtil; | 
						|
import lombok.extern.slf4j.Slf4j; | 
						|
import org.springframework.context.ApplicationContext; | 
						|
 | 
						|
import java.util.Date; | 
						|
 | 
						|
/** | 
						|
 * @author LJF | 
						|
 * @version 1.0 | 
						|
 * @project CHWS | 
						|
 * @description 电表运行策略 | 
						|
 * @date 2024-03-18 09:51:17 | 
						|
 */ | 
						|
@Slf4j | 
						|
public class WtMeterStrategy implements DeviceStrategy { | 
						|
 | 
						|
    ApplicationContext context = SpringBeanUtil.getApplicationContext(); | 
						|
 | 
						|
    DataResultService dataResultService = context.getBean(DataResultService.class); | 
						|
 | 
						|
    private static class SingletonHolder { | 
						|
        private static final WtMeterStrategy INSTANCE = new WtMeterStrategy(); | 
						|
    } | 
						|
 | 
						|
    private WtMeterStrategy() { | 
						|
        // 防止外部直接实例化 | 
						|
    } | 
						|
 | 
						|
    public static WtMeterStrategy getInstance() { | 
						|
        return WtMeterStrategy.SingletonHolder.INSTANCE; | 
						|
    } | 
						|
 | 
						|
    @Override | 
						|
    public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) { | 
						|
        String deviceAddr = deviceCodeParamEntity.getDeviceAddr(); | 
						|
        String brand = deviceCodeParamEntity.getBrand(); | 
						|
        String str = ""; | 
						|
        if (deviceAddr != null && deviceAddr.length() > 0) { | 
						|
            try { | 
						|
                if (StringUtils.isBlank(brand) || brand.equals("埃美柯")) { | 
						|
                    // 0 代表前面补充0,14 代表长度为14,d 代表参数为正数型 | 
						|
                    str = String.format("%014d", Long.parseLong(deviceAddr));//基表通讯号 | 
						|
                    // 转换位置 | 
						|
                    str = ExchangeStringUtil.changePosition(str); | 
						|
                    // 拼接功能码 | 
						|
                    str = "6810" + str + "0103901F00";   //水表读读数指令 | 
						|
                    // 检验和 | 
						|
                    String checkSum = ExchangeStringUtil.makeChecksum(str); | 
						|
                    str = "FEFEFE" + str + checkSum + "16"; | 
						|
                } else if (brand.equals("脉冲")) { | 
						|
                    str = ExchangeStringUtil.decToHex(deviceAddr); | 
						|
                    str = ExchangeStringUtil.addZeroForNum(str, 2); | 
						|
                    str = str + "0302020002";//读表累计值 | 
						|
                    String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 | 
						|
                    str = str + checkWord; | 
						|
                } | 
						|
            } catch (Exception e) { | 
						|
                e.printStackTrace(); | 
						|
                log.error("生成水表采集指令异常>>>>", e); | 
						|
            } | 
						|
        } | 
						|
        log.info("生成水表采集指令>>>>" + str); | 
						|
        return str.toUpperCase(); | 
						|
    } | 
						|
 | 
						|
    @Override | 
						|
    public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) { | 
						|
        String data = ""; | 
						|
        String meterId = ""; | 
						|
        if (dataStr.length() == 44 || dataStr.length() == 70 || dataStr.length() == 72) { | 
						|
            String checkStr = dataStr.substring(0, dataStr.length() - 4);//减去校验码 | 
						|
            String checkNum = ExchangeStringUtil.makeChecksum(checkStr); //生成校验码 | 
						|
            if (checkNum.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4, dataStr.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("水表报文检验失败: " + dataStr); | 
						|
            } | 
						|
        } else if (dataStr.length() == 18) { | 
						|
            String checkStr = dataStr.substring(0, dataStr.length() - 4);//检验报文 | 
						|
            byte[] strOrder = ExchangeStringUtil.hexStrToBinaryStr(checkStr); | 
						|
            int checkNum = CRC16.CRC16_MODBUS(strOrder); | 
						|
            String checkWord = ExchangeStringUtil.decToHex(String.valueOf(checkNum)); | 
						|
            checkWord = checkWord.substring(2, 4) + checkWord.substring(0, 2); | 
						|
            String sValue = null; | 
						|
            if (checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) { | 
						|
                meterId = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));//地址 | 
						|
                if (checkStr.substring(2, 4).equalsIgnoreCase("03")) { | 
						|
                    data = String.valueOf(Integer.parseInt(ExchangeStringUtil.hexToDec(checkStr.substring(6, 14))) / 10); //读数 | 
						|
                } | 
						|
            } else { | 
						|
                log.info("水表报文检验失败: " + dataStr); | 
						|
            } | 
						|
        } | 
						|
        log.info("水表表号: " + meterId + ",水表读数:" + data); | 
						|
        try { | 
						|
            if (!StringUtils.isBlank(data)) { | 
						|
                DataResultEntity dataResultEntity = new DataResultEntity(); | 
						|
                dataResultEntity.setDeviceAddr(meterId);//通讯编号 | 
						|
                dataResultEntity.setDeviceType("水表"); | 
						|
                dataResultEntity.setCurValue(Double.parseDouble(data));     //当前读数 | 
						|
                Date date = new Date(); | 
						|
                dataResultEntity.setCurDate(date);           //当前日期 | 
						|
                dataResultEntity.setBuildingId(buildingId); | 
						|
                dataResultService.saveDataResult(dataResultEntity); | 
						|
                log.info("水表数据保存数据库成功!楼栋名称:" + buildingName); | 
						|
            } | 
						|
        } catch (Exception e) { | 
						|
            e.printStackTrace(); | 
						|
            log.error("水表数据保存数据库失败!楼栋名称:" + buildingName); | 
						|
        } | 
						|
        if (!StringUtils.isBlank(data)) { | 
						|
            data = String.valueOf(Double.valueOf(data)); | 
						|
        } | 
						|
        return data; | 
						|
    } | 
						|
}
 | 
						|
 |