中央热水项目
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.

221 lines
12 KiB

package com.mh.user.strategy;
import com.mh.common.utils.StringUtils;
import com.mh.user.constants.Constant;
import com.mh.user.entity.DeviceCodeParamEntity;
import com.mh.user.service.NowDataService;
import com.mh.user.service.NowPublicDataService;
import com.mh.user.utils.ExchangeStringUtil;
import com.mh.user.utils.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
/**
* @author LJF
* @version 1.0
* @project CHWS
* @description 时间控制器策略
* @date 2024-03-18 09:51:17
*/
@Slf4j
public class TimeControlStrategy implements DeviceStrategy {
// 调用service
ApplicationContext context = SpringBeanUtil.getApplicationContext();
NowDataService nowDataService = context.getBean(NowDataService.class);
NowPublicDataService nowPublicDataService = context.getBean(NowPublicDataService.class);
private static class SingletonHolder {
private static final TimeControlStrategy INSTANCE = new TimeControlStrategy();
}
private TimeControlStrategy() {
// 防止外部直接实例化
}
public static TimeControlStrategy getInstance() {
return TimeControlStrategy.SingletonHolder.INSTANCE;
}
@Override
public String createOrders(DeviceCodeParamEntity deviceCodeParamEntity) {
String deviceAddr = deviceCodeParamEntity.getDeviceAddr();
String brand = deviceCodeParamEntity.getBrand();
String funCode = deviceCodeParamEntity.getFunCode();
String registerAddr = deviceCodeParamEntity.getRegisterAddr();
String registerSize = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(String.valueOf(deviceCodeParamEntity.getRegisterSize())), 4);
String dataValue = deviceCodeParamEntity.getDataValue();
String param = deviceCodeParamEntity.getParam();
String str = "";
// 根据品牌进行判断
if (deviceAddr != null && !deviceAddr.isEmpty()) {
str = ExchangeStringUtil.decToHex(deviceAddr);
str = ExchangeStringUtil.addZeroForNum(str, 2); //以0补位
if (!StringUtils.isBlank(brand) && Constant.BRAND_ALITA.equals(brand)) {
try {
if (!StringUtils.isBlank(funCode)) {
registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4); //寄存器地址
funCode = ExchangeStringUtil.addZeroForNum(funCode, 2); // 功能码
if (funCode.equals("03")) { //功能码,读
str = str + "03" + registerAddr + registerSize;
} else if (funCode.equals("10")) {//写
// 判断寄存器地址
registerAddr = registerAddr.toUpperCase();
if ("0108".equals(registerAddr)) {
// 1F1001080003060014001200225B97
str = str + funCode + registerAddr + "000306"
+ "00" + dataValue.substring(2, 4) // 年
+ "00" + dataValue.substring(4,6) // 月
+ "00" + dataValue.substring(6,8); // 日
} else if ("010C".equals(registerAddr)) {
// 1F10010C0004080015004300300002BA23
str = str + funCode + registerAddr + "000408"
+ "00" + dataValue.substring(8, 10) // 时
+ "00" + dataValue.substring(10,12) // 分
+ "0000" // 秒
+ "0002"; // 只写 写2设置日期,写1读取日期
} else if ("0041".equals(registerAddr)) {
str = str + funCode + registerAddr + "000204"
+ "00" + dataValue.substring(0, 2) // 分
+ "00" + dataValue.substring(2, 4); // 秒
} else if ("0044".equals(registerAddr)) {
str = str + funCode + registerAddr + "000204"
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.parseByte2HexStr(dataValue.substring(0, 8)), 4) // 1-8路
+ ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.parseByte2HexStr(dataValue.substring(8, 16)), 4); // 9-16路
}
} else if (funCode.equals("06")) {
str = str + funCode + registerAddr + ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.decToHex(dataValue), 4);
}
}
String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验
str = str + checkWord;
} catch (Exception e) {
log.error("生成阿丽塔时控指令出错!" + str, e);
}
} else {
try {
if (!StringUtils.isBlank(funCode)) {
registerAddr = ExchangeStringUtil.addZeroForNum(registerAddr, 4); //寄存器地址
funCode = ExchangeStringUtil.addZeroForNum(funCode, 2); // 功能码
if (funCode.equals("03")) { //功能码,读
if (param.equals("checkTime")) {
// 读取时间:0A 03 00 00 00 03 04 B0
str = str + "03" + registerAddr + "0003";
} else {
str = str + "03" + registerAddr + "0004";
}
} else if (funCode.equals("10")) {//写
if (!dataValue.equals("") && !param.equals("checkTime")) {
str = str + "10" + registerAddr + "000408" + dataValue;
} else {
// 校验时间:0A 10 00 00 00 03 06 00 24 01 10 08 59 48 CF
// 0A 10 00 00 00 03 06 00 24 01 10 09 40 8B 95
str = str + "10" + registerAddr + "00030600" + dataValue.substring(2);
}
}
}
String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验
str = str + checkWord;
} catch (Exception e) {
log.error("生成时控指令出错!" + str, e);
}
}
}
return str.toUpperCase();
}
@Override
public String analysisReceiveData(String dateStr, String deviceType, String registerAddr, String brand, String buildingId, String buildingName, String dataStr) {
String result = Constant.FAIL;
String checkStr = dataStr.substring(0, dataStr.length() - 4);
String checkWord = ExchangeStringUtil.getStrCRC16(checkStr);//生成校验码
if (!checkWord.equalsIgnoreCase(dataStr.substring(dataStr.length() - 4))) {
return result;
}
log.info("时控报文检验成功: " + dataStr);
//地址
String addr = ExchangeStringUtil.hexToDec(checkStr.substring(0, 2));
log.info("时控号: " + addr);
String data = "";
if (checkStr.substring(2, 4).equalsIgnoreCase("03")) {// 读
int rec = dataStr.length();
if (!StringUtils.isBlank(brand) && Constant.BRAND_ALITA.equals(brand)) {
if (rec == 14 && isExactlyDivisible("0040", registerAddr)) {
// 开关设置
// 16进制转2进制 10011
data = ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, rec - 4));
data = ExchangeStringUtil.addZeroForNum(data, 8);
// 再截取前四位转换成10进制
data = ExchangeStringUtil.hexToDec(data.substring(0, 4));
} else if (rec == 18 && isExactlyDivisible("0041", registerAddr)) {
// 时间设置
// 直接截取时,分
data = checkStr.substring(8,10)+checkStr.substring(12, 14);
} else if (rec == 14 && isExactlyDivisible("0043", registerAddr)) {
// 星期掩码
// 截取时间
data = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)), 8);
data = new StringBuilder(data).reverse().toString();
} else if (rec == 18 && isExactlyDivisible("0044", registerAddr)) {
// 定时控制继电器路数
// 截取1-8路,低8位 从高到低表示1-8路 1是执行动作。 0是保持
String multiple1 = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexString2binaryString(checkStr.substring(8, 10)), 8);
// 截取9-16路,低8位 从高到低表示9-16路 1是执行动作。 0是保持
String multiple2 = ExchangeStringUtil.addZeroForNum(ExchangeStringUtil.hexString2binaryString(checkStr.substring(12, 14)), 8);
data = multiple1 + multiple2;
} else if (rec == 38 && isExactlyDivisible("0010", registerAddr)) {
// 设备当前时间
// 直接截取年、月、日、小时、分、秒
data = checkStr.substring(8, 10)
+ checkStr.substring(12, 14)
+ checkStr.substring(16, 18)
+ checkStr.substring(22, 24)
+ checkStr.substring(26, 28)
+ checkStr.substring(30, 32);
}
} else {
if (rec == 26) { //读时间设置值
data = checkStr.substring(6, rec - 4);
String curTimeBegin1 = data.substring(0, 2) + ":" + data.substring(2, 4);
String curTimeEnd1 = data.substring(4, 6) + ":" + data.substring(6, 8);
String curTimeBegin2 = data.substring(8, 10) + ":" + data.substring(10, 12);
String curTimeEnd2 = data.substring(12, 14) + ":" + data.substring(14, 16);
} else if (rec == 22) { //读校对时间
// {"code":200,"msg":"2509031508","data":"2509031508","count":0}
data = checkStr.substring(8, rec - 4);
String strDate = "20" + data.substring(0, 2) + "-" + data.substring(2, 4) + "-" + data.substring(4, 6); //拼接日期
String strTime = data.substring(6, 8) + ":" + data.substring(8, 10); //拼接时间
}
}
result = data;
} else if (checkStr.substring(2, 4).equalsIgnoreCase("05")
|| checkStr.substring(2, 4).equalsIgnoreCase("10")
|| checkStr.substring(2,4).equalsIgnoreCase("06")
) {
log.info("时间: " + dateStr + ",时控ID: " + addr + ",操作成功! ");
return Constant.SUCCESS;
}
return result;
}
// 判断是否可以整除
private static boolean isExactlyDivisible(String baseAddr, String registerAddr) {
// 16进制转十进制
int baseAddrInt = ExchangeStringUtil.hexToDecimal(baseAddr);
int registerAddrInt = ExchangeStringUtil.hexToDecimal(registerAddr);
// 判断地址差值是否能被6整除
if (registerAddrInt >= baseAddrInt) {
int difference = registerAddrInt - baseAddrInt;
return difference % 6 == 0;
}
return false;
}
}