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