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.
171 lines
8.3 KiB
171 lines
8.3 KiB
package com.mh.user.strategy; |
|
|
|
import com.mh.common.utils.StringUtils; |
|
import com.mh.user.constants.Constant; |
|
import com.mh.user.entity.CollectionParamsManageEntity; |
|
import com.mh.user.entity.DataResultEntity; |
|
import com.mh.user.entity.DeviceCodeParamEntity; |
|
import com.mh.user.entity.DeviceInstallEntity; |
|
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("埃美柯") || 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, DeviceCodeParamEntity deviceCodeParamEntity) { |
|
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; |
|
} |
|
|
|
@Override |
|
public String analysisMQTTReceiveData(String dateStr, String registerAddr, String dataStr, String operateType, DeviceInstallEntity deviceInstallEntity, |
|
CollectionParamsManageEntity collectionParamsManageEntity) { |
|
String data = Constant.FAIL; |
|
if (Integer.parseInt(dataStr) < 0) { |
|
return data; |
|
} |
|
log.info("水表表号: " + deviceInstallEntity.getDeviceAddr() + ",水表读数:" + dataStr); |
|
// 考虑dataStr是否走大数或者走小数 |
|
if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>100 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) { |
|
dataStr = String.valueOf(deviceInstallEntity.getLastValue()); |
|
} |
|
try { |
|
if (!StringUtils.isBlank(dataStr)) { |
|
DataResultEntity dataResultEntity = new DataResultEntity(); |
|
dataResultEntity.setDeviceAddr(deviceInstallEntity.getDeviceAddr());//通讯编号 |
|
dataResultEntity.setDeviceType("水表"); |
|
dataResultEntity.setCurValue(Double.parseDouble(dataStr)); //当前读数 |
|
Date date = new Date(); |
|
dataResultEntity.setCurDate(date); //当前日期 |
|
dataResultEntity.setBuildingId(deviceInstallEntity.getBuildingId()); |
|
dataResultService.saveDataResult(dataResultEntity); |
|
log.info("水表数据保存数据库成功!楼栋名称:" + deviceInstallEntity.getBuildingName()); |
|
} |
|
} catch (Exception e) { |
|
log.error("水表数据保存数据库失败!楼栋名称:{}", deviceInstallEntity.getBuildingName(), e); |
|
} |
|
if (!StringUtils.isBlank(dataStr)) { |
|
data = String.valueOf(Double.valueOf(dataStr)); |
|
} |
|
return data; |
|
} |
|
}
|
|
|