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; } }