|
|
@ -2,12 +2,24 @@ package com.mh.user.strategy; |
|
|
|
|
|
|
|
|
|
|
|
import com.mh.common.utils.StringUtils; |
|
|
|
import com.mh.common.utils.StringUtils; |
|
|
|
import com.mh.user.constants.Constant; |
|
|
|
import com.mh.user.constants.Constant; |
|
|
|
|
|
|
|
import com.mh.user.entity.DataResultChEntity; |
|
|
|
|
|
|
|
import com.mh.user.entity.DataResultClEntity; |
|
|
|
|
|
|
|
import com.mh.user.entity.DeviceCodeParamEntity; |
|
|
|
import com.mh.user.entity.MeterManageEntity; |
|
|
|
import com.mh.user.entity.MeterManageEntity; |
|
|
|
|
|
|
|
import com.mh.user.service.DataResultService; |
|
|
|
|
|
|
|
import com.mh.user.service.ProjectInfoService; |
|
|
|
import com.mh.user.utils.ExchangeStringUtil; |
|
|
|
import com.mh.user.utils.ExchangeStringUtil; |
|
|
|
|
|
|
|
import com.mh.user.utils.SpringBeanUtil; |
|
|
|
|
|
|
|
import com.mh.user.utils.ThreadPoolService; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
|
|
import org.springframework.context.ApplicationContext; |
|
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.math.RoundingMode; |
|
|
|
import java.math.RoundingMode; |
|
|
|
|
|
|
|
import java.text.ParseException; |
|
|
|
|
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
|
|
|
|
import java.util.Date; |
|
|
|
|
|
|
|
import java.util.concurrent.ThreadPoolExecutor; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @author LJF |
|
|
|
* @author LJF |
|
|
@ -19,6 +31,14 @@ import java.math.RoundingMode; |
|
|
|
@Slf4j |
|
|
|
@Slf4j |
|
|
|
public class ModbusProtocolStrategy implements ProtocolStrategy { |
|
|
|
public class ModbusProtocolStrategy implements ProtocolStrategy { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用service
|
|
|
|
|
|
|
|
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
|
|
|
|
|
|
|
DataResultService dataResultService = context.getBean(DataResultService.class); |
|
|
|
|
|
|
|
ProjectInfoService projectInfoService = context.getBean(ProjectInfoService.class); |
|
|
|
|
|
|
|
ThreadPoolExecutor threadPoolService = ThreadPoolService.getInstance(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
|
|
|
|
|
|
|
|
|
|
|
private static class SingletonHolder { |
|
|
|
private static class SingletonHolder { |
|
|
|
private static final ModbusProtocolStrategy INSTANCE = new ModbusProtocolStrategy(); |
|
|
|
private static final ModbusProtocolStrategy INSTANCE = new ModbusProtocolStrategy(); |
|
|
|
} |
|
|
|
} |
|
|
@ -55,11 +75,11 @@ public class ModbusProtocolStrategy implements ProtocolStrategy { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String analysisReceiveData(MeterManageEntity meterManageEntity, String receiveData) { |
|
|
|
public String analysisReceiveData(DeviceCodeParamEntity deviceCodeParamEntity, String receiveData) { |
|
|
|
log.info("modbus标准协议:策略解析报文"); |
|
|
|
log.info("modbus标准协议:策略解析报文"); |
|
|
|
String checkStr = receiveData.substring(0, receiveData.length() - 4);//检验报文
|
|
|
|
String checkStr = receiveData.substring(0, receiveData.length() - 4);//检验报文
|
|
|
|
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码
|
|
|
|
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码
|
|
|
|
String sValue = null; |
|
|
|
String sValue = "0"; |
|
|
|
String rtData = Constant.FAIL; |
|
|
|
String rtData = Constant.FAIL; |
|
|
|
if (!checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { |
|
|
|
if (!checkWord.equalsIgnoreCase(receiveData.substring(receiveData.length() - 4))) { |
|
|
|
log.info("Modbus报文检验失败: {}", receiveData); |
|
|
|
log.info("Modbus报文检验失败: {}", receiveData); |
|
|
@ -67,27 +87,140 @@ public class ModbusProtocolStrategy implements ProtocolStrategy { |
|
|
|
} |
|
|
|
} |
|
|
|
// 开始解析: 地址+功能码+数据长度+数据域
|
|
|
|
// 开始解析: 地址+功能码+数据长度+数据域
|
|
|
|
// 截取数据长度
|
|
|
|
// 截取数据长度
|
|
|
|
String dataLength = receiveData.substring(6, 8); |
|
|
|
String dataLength = receiveData.substring(4, 6); |
|
|
|
int dataLengthInt = Integer.parseInt(dataLength, 16); |
|
|
|
int dataLengthInt = Integer.parseInt(dataLength, 16); |
|
|
|
// 截取数据域
|
|
|
|
// 截取数据域
|
|
|
|
String data = receiveData.substring(8, 8 + dataLengthInt * 2); |
|
|
|
String data = receiveData.substring(6, 6 + dataLengthInt * 2); |
|
|
|
// 判断
|
|
|
|
// 判断
|
|
|
|
switch (meterManageEntity.getDataType()) { |
|
|
|
switch (deviceCodeParamEntity.getDataType()) { |
|
|
|
case 0: |
|
|
|
case 0: |
|
|
|
|
|
|
|
case 1: |
|
|
|
// 16进制转十进制类型
|
|
|
|
// 16进制转十进制类型
|
|
|
|
sValue = ExchangeStringUtil.hexToDec(data); |
|
|
|
sValue = ExchangeStringUtil.hexToDec(data); |
|
|
|
// 保留位数
|
|
|
|
// 保留位数
|
|
|
|
sValue = (new BigDecimal(sValue)).divide(new BigDecimal(String.valueOf(meterManageEntity.getDigits() * 10)), 2, RoundingMode.HALF_UP).toString(); |
|
|
|
sValue = (new BigDecimal(sValue)).divide(new BigDecimal(String.valueOf(deviceCodeParamEntity.getDigit() * 10)), 2, RoundingMode.HALF_UP).toString(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
case 2: |
|
|
|
// 十六进制字符串转IEEE754浮点型
|
|
|
|
// 十六进制字符串转IEEE754浮点型
|
|
|
|
sValue = String.valueOf(ExchangeStringUtil.hexToSingle(data)); |
|
|
|
sValue = String.valueOf(ExchangeStringUtil.hexToSingle(data)); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
log.info("解析数据==>表号:{},寄存器地址:{},值:{}", meterManageEntity.getMtNum(), meterManageEntity.getRegisterAddr(), sValue); |
|
|
|
log.info("解析数据==>表号:{},寄存器地址:{},值:{}", deviceCodeParamEntity.getDeviceAddr(), deviceCodeParamEntity.getRegisterAddr(), sValue); |
|
|
|
|
|
|
|
// 入库数据
|
|
|
|
|
|
|
|
// 冷量表
|
|
|
|
|
|
|
|
if ("2".equals(deviceCodeParamEntity.getDeviceType())) { |
|
|
|
|
|
|
|
analysisCloudOrder485(sValue, deviceCodeParamEntity); |
|
|
|
|
|
|
|
} else if ("0".equals(deviceCodeParamEntity.getDeviceType())) { |
|
|
|
|
|
|
|
analysisChillerOrder485(sValue, deviceCodeParamEntity); |
|
|
|
|
|
|
|
} |
|
|
|
return sValue; |
|
|
|
return sValue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 解析冷水机组返回的数据 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void analysisChillerOrder485(final String data, final DeviceCodeParamEntity deviceCodeParam) { |
|
|
|
|
|
|
|
if (!Constant.CONTROL_WEB_FLAG) { |
|
|
|
|
|
|
|
Date date = new Date(); |
|
|
|
|
|
|
|
// 冷水机组的地址
|
|
|
|
|
|
|
|
String chillerAddr = deviceCodeParam.getDeviceAddr(); |
|
|
|
|
|
|
|
DataResultChEntity dataResultCh = new DataResultChEntity(); |
|
|
|
|
|
|
|
// 状态
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// 赋值给dataResultCh
|
|
|
|
|
|
|
|
initialDataResultCh(deviceCodeParam, dataResultCh, chillerAddr, date, data); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
|
|
log.error("冷水机报错:", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 格式化数据 |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param deviceCodeParam |
|
|
|
|
|
|
|
* @param dataResultCh |
|
|
|
|
|
|
|
* @param chillerAddr |
|
|
|
|
|
|
|
* @param date |
|
|
|
|
|
|
|
* @param data |
|
|
|
|
|
|
|
* @throws ParseException |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void initialDataResultCh(DeviceCodeParamEntity deviceCodeParam, DataResultChEntity dataResultCh, String chillerAddr, Date date, String data) throws ParseException { |
|
|
|
|
|
|
|
dataResultCh.setDeviceAddr(chillerAddr); |
|
|
|
|
|
|
|
dataResultCh.setDeviceType(deviceCodeParam.getDeviceType()); |
|
|
|
|
|
|
|
dataResultCh.setCurDate(date); |
|
|
|
|
|
|
|
dataResultCh.setCurValue(data); |
|
|
|
|
|
|
|
dataResultCh.setRegisterAddr(deviceCodeParam.getRegisterAddr()); |
|
|
|
|
|
|
|
dataResultCh.setRegisterName(deviceCodeParam.getRegisterName()); |
|
|
|
|
|
|
|
dataResultCh.setGrade(deviceCodeParam.getGrade()); |
|
|
|
|
|
|
|
dataResultCh.setFunCode(deviceCodeParam.getFunCode()); |
|
|
|
|
|
|
|
dataResultCh.setProjectId(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
String projectName = projectInfoService.selectName(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
log.info("冷水机:" + chillerAddr + ",状态:" + data + ",项目名称:" + projectName); |
|
|
|
|
|
|
|
dataResultService.saveDataResultChiller(dataResultCh); |
|
|
|
|
|
|
|
dataResultService.deleteDataResultNow(deviceCodeParam.getDeviceAddr(), deviceCodeParam.getDeviceType(), deviceCodeParam.getRegisterAddr(), deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
log.info("冷水机保存成功!项目名称:" + projectName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//解析冷量表
|
|
|
|
|
|
|
|
public void analysisCloudOrder485(final String data, final DeviceCodeParamEntity deviceCodeParam) { |
|
|
|
|
|
|
|
threadPoolService.execute(() -> { |
|
|
|
|
|
|
|
//创建SimpleDateFormat对象,指定样式 2019-05-13 22:39:30
|
|
|
|
|
|
|
|
Date date = new Date(); |
|
|
|
|
|
|
|
String dateStr = sdf1.format(date); |
|
|
|
|
|
|
|
String cloudId = deviceCodeParam.getDeviceAddr(); |
|
|
|
|
|
|
|
DataResultChEntity dataResultCh = new DataResultChEntity(); |
|
|
|
|
|
|
|
DataResultClEntity dataResultCl = new DataResultClEntity(); |
|
|
|
|
|
|
|
String registerAddr = deviceCodeParam.getRegisterAddr(); |
|
|
|
|
|
|
|
if (ExchangeStringUtil.isInDate(date, "00:00:00", "00:00:30")) { |
|
|
|
|
|
|
|
dateStr = dateStr.substring(0, 17) + "00"; |
|
|
|
|
|
|
|
System.out.println("插入时间00" + dateStr); |
|
|
|
|
|
|
|
} else if (ExchangeStringUtil.isInDate(date, "00:00:30", "00:00:59")) { |
|
|
|
|
|
|
|
dateStr = dateStr.substring(0, 17) + "30"; |
|
|
|
|
|
|
|
System.out.println("插入时间30" + dateStr); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
if (registerAddr.equals("0004") || registerAddr.equals("0014")) { |
|
|
|
|
|
|
|
dataResultCh.setDeviceAddr(cloudId); |
|
|
|
|
|
|
|
dataResultCh.setDeviceType(deviceCodeParam.getDeviceType()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dataResultCh.setCurDate(sdf1.parse(dateStr)); |
|
|
|
|
|
|
|
dataResultCh.setCurValue(data); |
|
|
|
|
|
|
|
dataResultCh.setRegisterAddr(deviceCodeParam.getRegisterAddr()); |
|
|
|
|
|
|
|
dataResultCh.setRegisterName(deviceCodeParam.getRegisterName()); |
|
|
|
|
|
|
|
dataResultCh.setGrade(deviceCodeParam.getGrade()); |
|
|
|
|
|
|
|
dataResultCh.setProjectId(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
dataResultCh.setGrade(deviceCodeParam.getGrade()); |
|
|
|
|
|
|
|
String projectName = projectInfoService.selectName(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
log.info("冷量计==>{},寄存器地址==>{},读数==>{},项目名称==>{}", cloudId, registerAddr, dataResultCh.getCurValue(), projectName); |
|
|
|
|
|
|
|
dataResultService.saveDataResultCh(dataResultCh); |
|
|
|
|
|
|
|
log.info("冷量计瞬时冷量/流量保存数据库成功!项目名称:{}", projectName); |
|
|
|
|
|
|
|
} else if (registerAddr.equals("0050")) { |
|
|
|
|
|
|
|
dataResultCl.setDeviceAddr(cloudId); |
|
|
|
|
|
|
|
dataResultCl.setDeviceType(deviceCodeParam.getDeviceType()); |
|
|
|
|
|
|
|
dataResultCh.setCurDate(sdf1.parse(dateStr)); |
|
|
|
|
|
|
|
BigDecimal lData = new BigDecimal(data); |
|
|
|
|
|
|
|
dataResultCl.setCurValue(lData);//字符串转整型
|
|
|
|
|
|
|
|
dataResultCl.setRegisterAddr(deviceCodeParam.getRegisterAddr()); |
|
|
|
|
|
|
|
dataResultCl.setRegisterName(deviceCodeParam.getRegisterName()); |
|
|
|
|
|
|
|
dataResultCl.setGrade(deviceCodeParam.getGrade()); |
|
|
|
|
|
|
|
dataResultCl.setProjectId(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
String projectName = projectInfoService.selectName(deviceCodeParam.getProjectId()); |
|
|
|
|
|
|
|
log.info("冷量计==>{},寄存器地址==>{},累计读数==>{},项目名称==>{}", cloudId, registerAddr, lData, projectName); |
|
|
|
|
|
|
|
if (lData.intValue() < 99999999) { |
|
|
|
|
|
|
|
if (lData.intValue() != 2231365) { |
|
|
|
|
|
|
|
dataResultService.saveDataResultCl(dataResultCl); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
log.info("冷量计累计保存数据成功!项目名称:{}", projectName); |
|
|
|
|
|
|
|
dataResultService.saveDataResultCl_bak(dataResultCl); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
|
|
log.error("保存冷量计数据失败!", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|