Compare commits
No commits in common. '2cedf6c143d5f1b5c2b5bf0c5c2867dc225345bc' and 'ab9cd2915f21a222906c6dc37dc9927f034ca5b2' have entirely different histories.
2cedf6c143
...
ab9cd2915f
32 changed files with 147 additions and 784 deletions
@ -1,193 +0,0 @@ |
|||||||
package com.mh.user.job; |
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject; |
|
||||||
import com.mh.common.http.HttpResult; |
|
||||||
import com.mh.user.constants.Constant; |
|
||||||
import com.mh.user.entity.CollectionParamsManageEntity; |
|
||||||
import com.mh.user.model.SerialPortModel; |
|
||||||
import com.mh.user.service.CollectionParamsManageService; |
|
||||||
import com.mh.user.service.DeviceControlService; |
|
||||||
import com.mh.user.utils.ExchangeStringUtil; |
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
import org.springframework.scheduling.annotation.Scheduled; |
|
||||||
import org.springframework.stereotype.Component; |
|
||||||
|
|
||||||
import java.time.LocalDate; |
|
||||||
import java.time.ZoneId; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Date; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.stream.Collectors; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author LJF |
|
||||||
* @version 1.0 |
|
||||||
* @project CHWS |
|
||||||
* @description 定时开关机热泵 |
|
||||||
* @date 2026-06-04 13:45:02 |
|
||||||
*/ |
|
||||||
@Slf4j |
|
||||||
@Component |
|
||||||
public class StartOrStopHotpumpJob { |
|
||||||
|
|
||||||
private final CollectionParamsManageService collectionParamsManageService; |
|
||||||
|
|
||||||
private final DeviceControlService deviceControlService; |
|
||||||
|
|
||||||
public StartOrStopHotpumpJob(CollectionParamsManageService collectionParamsManageService, DeviceControlService deviceControlService) { |
|
||||||
this.collectionParamsManageService = collectionParamsManageService; |
|
||||||
this.deviceControlService = deviceControlService; |
|
||||||
} |
|
||||||
|
|
||||||
@Scheduled(cron = "0 0/1 * * * ?") |
|
||||||
public void startOrStopHotpump() { |
|
||||||
log.info("定时开关机热泵开始"); |
|
||||||
// 查询定时时间
|
|
||||||
List<CollectionParamsManageEntity> paramsManageEntities = collectionParamsManageService.selectAllCPMList(); |
|
||||||
// 过滤获取paramTypeGroupId为3的数据
|
|
||||||
List<CollectionParamsManageEntity> filterList = paramsManageEntities.stream().filter(entity -> entity.getParamTypeGroupId() == 3).collect(Collectors.toList()); |
|
||||||
// 再根据device_install_id进行分组
|
|
||||||
Map<Long, List<CollectionParamsManageEntity>> listMap = filterList.stream().collect(Collectors.groupingBy(CollectionParamsManageEntity::getDeviceInstallId)); |
|
||||||
for (Map.Entry<Long, List<CollectionParamsManageEntity>> entry : listMap.entrySet()) { |
|
||||||
List<CollectionParamsManageEntity> value = entry.getValue(); |
|
||||||
// 查看是否启动定时,register_addr = START_TIME1的cur_value值是否等于1,
|
|
||||||
CollectionParamsManageEntity startTime1 = value.stream().filter(entity -> entity.getRegisterAddr().equals("START_TIME1")).findFirst().orElse(null); |
|
||||||
if (startTime1 != null && startTime1.getCurValue().intValue() == 1) { |
|
||||||
// 同时查看对应的设备是否是开机状态,同时判断curTime是否是今天,如果是开机状态则不执行定时开关机
|
|
||||||
CollectionParamsManageEntity entity1 = paramsManageEntities.stream().filter(entity -> entity.getDeviceInstallId().equals(entry.getKey())) |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("B000")) |
|
||||||
.filter(entity -> entity.getCurTime() != null) |
|
||||||
.filter(entity -> entity.getCurValue().intValue() == 1).findFirst().orElse(null); |
|
||||||
// 判断设备状态更新时间是否是今天
|
|
||||||
boolean isTodayUpdate = false; |
|
||||||
if (entity1 != null && entity1.getCurTime() != null) { |
|
||||||
Date curTime = entity1.getCurTime(); |
|
||||||
LocalDate updateDate = curTime.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate(); |
|
||||||
java.time.LocalDate today = java.time.LocalDate.now(); |
|
||||||
isTodayUpdate = updateDate.equals(today); |
|
||||||
log.info("设备{}的状态更新时间: {}, 是否是今天: {}", entry.getKey(), curTime, isTodayUpdate); |
|
||||||
} |
|
||||||
|
|
||||||
// 如果设备已开机且状态是今天更新的,则不执行定时开关机
|
|
||||||
if (entity1 != null && entity1.getCurValue().intValue() == 1 && isTodayUpdate) { |
|
||||||
log.info("设备{}已开机且状态为今天更新,不执行定时开关机", entry.getKey()); |
|
||||||
} else { |
|
||||||
|
|
||||||
// value过滤,开始查看当前时间是否是定时时间,register_name分别是
|
|
||||||
//OPEN_HOUR_TIME1:开始小时
|
|
||||||
//OPEN_MIN_TIME1:开始分钟
|
|
||||||
//CLOSE_HOUR_TIME1:结束小时
|
|
||||||
//CLOSE_MIN_TIME1:结束分钟
|
|
||||||
// 这几个查询出来在拼接成时间范围,然后判断当前时间是否在范围内,如果在范围内则执行定时开关机
|
|
||||||
// 获取定时开关机参数
|
|
||||||
CollectionParamsManageEntity openHour = value.stream() |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("OPEN_HOUR_TIME1")) |
|
||||||
.findFirst().orElse(null); |
|
||||||
CollectionParamsManageEntity openMin = value.stream() |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("OPEN_MIN_TIME1")) |
|
||||||
.findFirst().orElse(null); |
|
||||||
CollectionParamsManageEntity closeHour = value.stream() |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("CLOSE_HOUR_TIME1")) |
|
||||||
.findFirst().orElse(null); |
|
||||||
CollectionParamsManageEntity closeMin = value.stream() |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("CLOSE_MIN_TIME1")) |
|
||||||
.findFirst().orElse(null); |
|
||||||
|
|
||||||
// 检查所有定时参数是否都存在
|
|
||||||
if (openHour != null && openMin != null && closeHour != null && closeMin != null) { |
|
||||||
// 获取当前时间
|
|
||||||
java.time.LocalDateTime now = java.time.LocalDateTime.now(); |
|
||||||
int currentHour = now.getHour(); |
|
||||||
int currentMinute = now.getMinute(); |
|
||||||
int currentTime = currentHour * 100 + currentMinute; // 格式化为 HHmm
|
|
||||||
|
|
||||||
// 计算开始时间和结束时间
|
|
||||||
int startTime = openHour.getCurValue().intValue() * 100 + openMin.getCurValue().intValue(); |
|
||||||
int endTime = closeHour.getCurValue().intValue() * 100 + closeMin.getCurValue().intValue(); |
|
||||||
|
|
||||||
log.info("设备{}的定时时间 - 当前: {}, 开始: {}, 结束: {}", entry.getKey(), currentTime, startTime, endTime); |
|
||||||
|
|
||||||
// 判断当前时间是否在定时范围内
|
|
||||||
boolean isInTimeRange = false; |
|
||||||
if (startTime <= endTime) { |
|
||||||
// 正常情况:开始时间 <= 结束时间
|
|
||||||
isInTimeRange = currentTime >= startTime && currentTime <= endTime; |
|
||||||
} else { |
|
||||||
// 跨天情况:开始时间 > 结束时间(如 22:00 ~ 06:00)
|
|
||||||
isInTimeRange = currentTime >= startTime || currentTime <= endTime; |
|
||||||
} |
|
||||||
|
|
||||||
if (isInTimeRange) { |
|
||||||
// 在时间范围内,执行开机操作
|
|
||||||
log.info("设备{}在定时范围内,执行开机操作", entry.getKey()); |
|
||||||
executeHotPumpControl(entry.getKey(), paramsManageEntities, "1"); |
|
||||||
} else { |
|
||||||
// 不在时间范围内,执行关机操作
|
|
||||||
log.info("设备{}不在定时范围内,执行关机操作", entry.getKey()); |
|
||||||
executeHotPumpControl(entry.getKey(), paramsManageEntities, "0"); |
|
||||||
} |
|
||||||
} else { |
|
||||||
log.warn("设备{}的定时参数不完整", entry.getKey()); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
log.info("定时开关机热泵结束"); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 执行热泵开关机控制 |
|
||||||
* @param deviceInstallId 设备安装ID |
|
||||||
* @param params 参数列表 |
|
||||||
* @param command 命令:1-开机,0-关机 |
|
||||||
*/ |
|
||||||
private void executeHotPumpControl(Long deviceInstallId, List<CollectionParamsManageEntity> params, String command) { |
|
||||||
try { |
|
||||||
// 获取设备信息
|
|
||||||
CollectionParamsManageEntity deviceInfo = params.stream() |
|
||||||
.filter(entity -> entity.getDeviceInstallId().equals(deviceInstallId)) |
|
||||||
.filter(entity -> entity.getRegisterAddr().equals("B000")) |
|
||||||
.findFirst().orElse(null); |
|
||||||
|
|
||||||
if (deviceInfo == null) { |
|
||||||
log.error("未找到设备{}的开关机寄存器信息", deviceInstallId); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
// 检查当前状态,如果已经是目标状态则不执行
|
|
||||||
if (deviceInfo.getCurValue() != null && deviceInfo.getCurValue().intValue() == Integer.parseInt(command)) { |
|
||||||
log.info("设备{}已是目标状态{},无需操作", deviceInstallId, command); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
// 构建串口通信参数
|
|
||||||
SerialPortModel serialPortModel = new SerialPortModel(); |
|
||||||
serialPortModel.setCpmId(String.valueOf(deviceInfo.getId())); |
|
||||||
serialPortModel.setDataValue(command); |
|
||||||
serialPortModel.setParam(""); |
|
||||||
|
|
||||||
// 调用设备控制服务执行开关机
|
|
||||||
List<SerialPortModel> paramList = new ArrayList<>(); |
|
||||||
paramList.add(serialPortModel); |
|
||||||
|
|
||||||
try { |
|
||||||
Constant.WEB_FLAG = true; //单抄,暂时停止采集
|
|
||||||
Thread.sleep(1000); |
|
||||||
String rtData = deviceControlService.readOrWriteDevice(paramList, Constant.WRITE); |
|
||||||
if (ExchangeStringUtil.getJSONType(rtData)) { |
|
||||||
// Map map = JSONObject.parseObject(rtData);
|
|
||||||
log.info("设备{}{}成功", deviceInstallId, "1".equals(command) ? "开机" : "关机"); |
|
||||||
} else { |
|
||||||
log.error("设备{}{}失败,结果: {}", deviceInstallId, "1".equals(command) ? "开机" : "关机", rtData); |
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
Constant.WEB_FLAG = false; //单抄,恢复采集
|
|
||||||
} finally { |
|
||||||
Constant.WEB_FLAG = false; //单抄,恢复采集
|
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
log.error("执行设备{}开关机控制异常", deviceInstallId, e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1,312 +0,0 @@ |
|||||||
package com.mh.user.utils; |
|
||||||
|
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.function.Function; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author LJF |
|
||||||
* @version 1.0 |
|
||||||
* @project CHWS |
|
||||||
* @description 正帝热泵协议解析保存到数据库的值 |
|
||||||
* @date 2026-05-25 17:15:42 |
|
||||||
*/ |
|
||||||
public class XK814ModbusParamReadIntoDBUtil { |
|
||||||
/** |
|
||||||
* XK814 冷热水机 Modbus 协议 V1.0 解析器(第三张表) |
|
||||||
* 地址范围:A000 ~ B009, AFFF |
|
||||||
*/ |
|
||||||
// ==================== 地址常量(字符串格式)====================
|
|
||||||
public static final String ADDR_DISPLAY_WATER_TEMP = "A000"; // 40960
|
|
||||||
public static final String ADDR_TANK_TEMP = "A001"; // 40961
|
|
||||||
public static final String ADDR_OUTLET_TEMP = "A002"; // 40962
|
|
||||||
public static final String ADDR_INLET_TEMP = "A003"; // 40963
|
|
||||||
public static final String ADDR_AMBIENT_TEMP = "A004"; // 40964
|
|
||||||
public static final String ADDR_COIL1_TEMP = "A005"; // 40965
|
|
||||||
public static final String ADDR_SUCTION1_TEMP = "A006"; // 40966
|
|
||||||
public static final String ADDR_EXHAUST1_TEMP = "A007"; // 40967
|
|
||||||
public static final String ADDR_VALVE_AFTER1_OR_RETURN = "A008"; // 40968
|
|
||||||
public static final String ADDR_RESERVED_A009 = "A009"; |
|
||||||
public static final String ADDR_RESERVED_A00A = "A00A"; |
|
||||||
public static final String ADDR_MAIN_EXP_VALVE1_OPEN = "A00B"; // 40971
|
|
||||||
public static final String ADDR_AUX_EXP_VALVE1_OPEN = "A00C"; // 40972
|
|
||||||
public static final String ADDR_COMP1_CURRENT = "A00D"; // 40973
|
|
||||||
public static final String ADDR_COIL2_TEMP = "A00E"; // 40974
|
|
||||||
public static final String ADDR_SUCTION2_TEMP = "A00F"; // 40975
|
|
||||||
public static final String ADDR_EXHAUST2_TEMP = "A010"; // 40976
|
|
||||||
public static final String ADDR_VALVE_AFTER2_TEMP = "A011"; // 40977
|
|
||||||
public static final String ADDR_RESERVED_A012 = "A012"; |
|
||||||
public static final String ADDR_RESERVED_A013 = "A013"; |
|
||||||
public static final String ADDR_MAIN_EXP_VALVE2_OPEN = "A014"; // 40980
|
|
||||||
public static final String ADDR_AUX_EXP_VALVE2_OPEN = "A015"; // 40981
|
|
||||||
public static final String ADDR_COMP2_CURRENT = "A016"; // 40982
|
|
||||||
public static final String ADDR_RECOVERABLE_FAULT = "A017"; // 40983
|
|
||||||
public static final String ADDR_UNRECOVERABLE_FAULT = "A018"; // 40984
|
|
||||||
public static final String ADDR_VERSION_INFO = "A019"; // 40985
|
|
||||||
public static final String ADDR_INPUT_SWITCH_STATUS = "A01A"; // 40986
|
|
||||||
public static final String ADDR_WATER_LEVEL_SWITCH = "A01B"; // 40987
|
|
||||||
public static final String ADDR_OUTPUT1_STATUS = "A01C"; // 40988
|
|
||||||
public static final String ADDR_OUTPUT2_STATUS = "A01D"; // 40989
|
|
||||||
public static final String ADDR_OUTPUT3_STATUS = "A01E"; // 40990
|
|
||||||
public static final String ADDR_DIP_SWITCH = "A01F"; // 40991
|
|
||||||
public static final String ADDR_MAINBOARD_TYPE = "A020"; // 40992
|
|
||||||
public static final String ADDR_CONSTANT_TEMP_SET = "AFFF"; // 45055
|
|
||||||
public static final String ADDR_ON_OFF = "B000"; // 45056
|
|
||||||
public static final String ADDR_COOL_SET_TEMP = "B001"; // 45057
|
|
||||||
public static final String ADDR_HEAT_SET_TEMP = "B002"; // 45058
|
|
||||||
public static final String ADDR_MODE = "B003"; // 45059
|
|
||||||
public static final String ADDR_HOT_WATER_SET_TEMP = "B004"; // 45060
|
|
||||||
public static final String ADDR_FORCE_ELECTRIC_HEAT = "B005"; // 45061
|
|
||||||
public static final String ADDR_FORCE_DEFROST = "B006"; // 45062
|
|
||||||
public static final String ADDR_RESERVED_B007 = "B007"; |
|
||||||
public static final String ADDR_RETURN_VALVE_TIMER = "B008"; // 45064
|
|
||||||
public static final String ADDR_SUPPLY_VALVE_TIMER = "B009"; // 45065
|
|
||||||
|
|
||||||
// ==================== 解析器映射表 ====================
|
|
||||||
private static final Map<String, Function<Integer, Object>> PARSERS = new HashMap<>(); |
|
||||||
|
|
||||||
// ==================== 编码器映射表(写操作) ====================
|
|
||||||
private static final Map<String, Function<Object, Integer>> ENCODERS = new HashMap<>(); |
|
||||||
|
|
||||||
static { |
|
||||||
// ---------- TEMP1 类型(无符号byte,低8位有效)----------
|
|
||||||
// 公式:温度 = (raw - 64) / 2,raw=1 表示传感器故障/未接
|
|
||||||
Function<Integer, Object> temp1Parser = v -> parseTemp1(v & 0xFF); |
|
||||||
Function<Object, Integer> temp1Encoder = val -> encodeTemp1((Double) val); |
|
||||||
|
|
||||||
// ---------- TEMP2 类型(无符号byte,低8位有效)----------
|
|
||||||
// 公式:温度 = raw - 32,raw=1 表示传感器故障/未接
|
|
||||||
Function<Integer, Object> temp2Parser = v -> parseTemp2(v & 0xFF); |
|
||||||
Function<Object, Integer> temp2Encoder = val -> encodeTemp2((Integer) val); |
|
||||||
|
|
||||||
// ---------- DIGI1 类型(无符号byte,低8位有效)----------
|
|
||||||
Function<Integer, Object> digi1Parser = v -> v & 0xFF; |
|
||||||
Function<Object, Integer> digi1Encoder = val -> ((Number) val).intValue() & 0xFF ; |
|
||||||
|
|
||||||
// ---------- DIG2 类型(16位无符号整型)----------
|
|
||||||
Function<Integer, Object> dig2Parser = v -> v & 0xFFFF; |
|
||||||
Function<Object, Integer> dig2Encoder = val -> ((Number) val).intValue() & 0xFFFF; |
|
||||||
|
|
||||||
// 地址配置(解析器 + 编码器)
|
|
||||||
// 温度读取地址(只读)
|
|
||||||
String[] temp1Addrs = {ADDR_DISPLAY_WATER_TEMP, ADDR_TANK_TEMP, ADDR_OUTLET_TEMP, |
|
||||||
ADDR_INLET_TEMP, ADDR_AMBIENT_TEMP, ADDR_COIL1_TEMP, ADDR_SUCTION1_TEMP, |
|
||||||
ADDR_VALVE_AFTER1_OR_RETURN, ADDR_COIL2_TEMP, ADDR_SUCTION2_TEMP, |
|
||||||
ADDR_VALVE_AFTER2_TEMP}; |
|
||||||
for (String addr : temp1Addrs) { |
|
||||||
PARSERS.put(addr, temp1Parser); |
|
||||||
// 这些是只读地址,不设置编码器
|
|
||||||
} |
|
||||||
// TEMP2 只读
|
|
||||||
String[] temp2Addrs = {ADDR_EXHAUST1_TEMP, ADDR_EXHAUST2_TEMP}; |
|
||||||
for (String addr : temp2Addrs) { |
|
||||||
PARSERS.put(addr, temp2Parser); |
|
||||||
} |
|
||||||
|
|
||||||
// DIG2 只读
|
|
||||||
String[] dig2Addrs = {ADDR_MAIN_EXP_VALVE1_OPEN, ADDR_AUX_EXP_VALVE1_OPEN, |
|
||||||
ADDR_MAIN_EXP_VALVE2_OPEN, ADDR_AUX_EXP_VALVE2_OPEN}; |
|
||||||
for (String addr : dig2Addrs) { |
|
||||||
PARSERS.put(addr, dig2Parser); |
|
||||||
} |
|
||||||
|
|
||||||
// DIGI1 只读
|
|
||||||
String[] digi1Addrs = {ADDR_COMP1_CURRENT, ADDR_COMP2_CURRENT, |
|
||||||
ADDR_RECOVERABLE_FAULT, ADDR_UNRECOVERABLE_FAULT}; |
|
||||||
for (String addr : digi1Addrs) { |
|
||||||
PARSERS.put(addr, digi1Parser); |
|
||||||
} |
|
||||||
|
|
||||||
// 版本号(特殊解析)
|
|
||||||
PARSERS.put(ADDR_VERSION_INFO, XK814ModbusParamReadIntoDBUtil::parseVersion); |
|
||||||
// 位域状态
|
|
||||||
PARSERS.put(ADDR_INPUT_SWITCH_STATUS, XK814ModbusParamReadIntoDBUtil::parseInputSwitchStatus); |
|
||||||
PARSERS.put(ADDR_WATER_LEVEL_SWITCH, XK814ModbusParamReadIntoDBUtil::parseWaterLevelSwitch); |
|
||||||
PARSERS.put(ADDR_OUTPUT1_STATUS, XK814ModbusParamReadIntoDBUtil::parseOutput1Status); |
|
||||||
PARSERS.put(ADDR_OUTPUT2_STATUS, XK814ModbusParamReadIntoDBUtil::parseOutput2Status); |
|
||||||
PARSERS.put(ADDR_OUTPUT3_STATUS, XK814ModbusParamReadIntoDBUtil::parseOutput3Status); |
|
||||||
PARSERS.put(ADDR_DIP_SWITCH, XK814ModbusParamReadIntoDBUtil::parseDipSwitch); |
|
||||||
PARSERS.put(ADDR_MAINBOARD_TYPE, XK814ModbusParamReadIntoDBUtil::parseMainboardType); |
|
||||||
|
|
||||||
// ========== 可读写地址 ==========
|
|
||||||
// AFFFH 恒温设置温度 (TEMP2)
|
|
||||||
PARSERS.put(ADDR_CONSTANT_TEMP_SET, temp2Parser); |
|
||||||
ENCODERS.put(ADDR_CONSTANT_TEMP_SET, temp2Encoder); |
|
||||||
|
|
||||||
// B000H 开关机 (0关机,1开机)
|
|
||||||
PARSERS.put(ADDR_ON_OFF, v -> (v & 0xFF) == 0 ? "0" : "1"); |
|
||||||
ENCODERS.put(ADDR_ON_OFF, val -> (val.equals("开机") ? 1 : 0) & 0xFF); |
|
||||||
|
|
||||||
// B001H 制冷设置温度 (TEMP2)
|
|
||||||
PARSERS.put(ADDR_COOL_SET_TEMP, temp2Parser); |
|
||||||
ENCODERS.put(ADDR_COOL_SET_TEMP, temp2Encoder); |
|
||||||
// B002H 制热设置温度 (TEMP2)
|
|
||||||
PARSERS.put(ADDR_HEAT_SET_TEMP, temp2Parser); |
|
||||||
ENCODERS.put(ADDR_HEAT_SET_TEMP, temp2Encoder); |
|
||||||
// B003H 运行模式 (0制热,1制冷,2恒温)
|
|
||||||
PARSERS.put(ADDR_MODE, v -> { |
|
||||||
int mode = v & 0xFF; |
|
||||||
switch (mode) { |
|
||||||
case 0: |
|
||||||
return "0"; |
|
||||||
case 1: |
|
||||||
return "1"; |
|
||||||
case 2: |
|
||||||
return "2"; |
|
||||||
default: |
|
||||||
return "99"; |
|
||||||
} |
|
||||||
}); |
|
||||||
ENCODERS.put(ADDR_MODE, val -> { |
|
||||||
String mode = (String) val; |
|
||||||
switch (mode) { |
|
||||||
case "制热": |
|
||||||
return 0; |
|
||||||
case "制冷": |
|
||||||
return 1; |
|
||||||
case "恒温": |
|
||||||
return 2; |
|
||||||
default: |
|
||||||
throw new IllegalArgumentException("无效模式: " + mode); |
|
||||||
} |
|
||||||
}); |
|
||||||
// B004H 热水设置温度 (TEMP2)
|
|
||||||
PARSERS.put(ADDR_HOT_WATER_SET_TEMP, temp2Parser); |
|
||||||
ENCODERS.put(ADDR_HOT_WATER_SET_TEMP, temp2Encoder); |
|
||||||
// B005H 强制电加热
|
|
||||||
PARSERS.put(ADDR_FORCE_ELECTRIC_HEAT, v -> (v & 0xFF) == 0 ? "0" : "1"); |
|
||||||
ENCODERS.put(ADDR_FORCE_ELECTRIC_HEAT, val -> val.equals("开启强制") ? 1 : 0); |
|
||||||
// B006H 强制除霜
|
|
||||||
PARSERS.put(ADDR_FORCE_DEFROST, v -> (v & 0xFF) == 0 ? "0" : "1"); |
|
||||||
ENCODERS.put(ADDR_FORCE_DEFROST, val -> val.equals("开启强制") ? 1 : 0); |
|
||||||
// B008H 回水阀定时开关 (bit0)
|
|
||||||
PARSERS.put(ADDR_RETURN_VALVE_TIMER, v -> ((v & 01) == 0) ? "0" : "1"); |
|
||||||
ENCODERS.put(ADDR_RETURN_VALVE_TIMER, val -> (val.equals("开启") ? 1 : 0) & 01); |
|
||||||
// B009H 供水阀定时开关 (bit0)
|
|
||||||
PARSERS.put(ADDR_SUPPLY_VALVE_TIMER, v -> ((v & 01) == 0) ? "0" : "1"); |
|
||||||
ENCODERS.put(ADDR_SUPPLY_VALVE_TIMER, val -> (val.equals("开启") ? 1 : 0) & 01); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 解析寄存器值 |
|
||||||
* |
|
||||||
* @param address 寄存器地址(字符串格式,如 "A000") |
|
||||||
* @param value 寄存器原始值(0~65535) |
|
||||||
* @return 解析后的物理值,若地址未定义则返回 null |
|
||||||
*/ |
|
||||||
public static Object parse(String address, int value) { |
|
||||||
Function<Integer, Object> parser = PARSERS.get(address); |
|
||||||
if (parser == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
return parser.apply(value); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 将物理值编码为寄存器值(用于写操作) |
|
||||||
* |
|
||||||
* @param address 寄存器地址(字符串格式,如 "A000") |
|
||||||
* @param physicalValue 物理值(类型需与协议匹配) |
|
||||||
* @return 要写入寄存器的整数值,若地址不支持写或类型错误则抛出异常 |
|
||||||
*/ |
|
||||||
public static int encode(String address, Object physicalValue) { |
|
||||||
Function<Object, Integer> encoder = ENCODERS.get(address); |
|
||||||
if (encoder == null) { |
|
||||||
throw new UnsupportedOperationException("地址 " + address + " 不支持写操作"); |
|
||||||
} |
|
||||||
return encoder.apply(physicalValue); |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== 私有解析/编码辅助方法 ====================
|
|
||||||
|
|
||||||
// TEMP1 解析:温度 = (raw - 64)/2,raw=1 表示故障
|
|
||||||
private static Double parseTemp1(int raw) { |
|
||||||
if (raw == 1) return 1.0; // 传感器故障或未接
|
|
||||||
return (raw - 64) / 2.0; |
|
||||||
} |
|
||||||
|
|
||||||
// TEMP1 编码:给定温度(Double),返回 raw 值
|
|
||||||
private static int encodeTemp1(Double temp) { |
|
||||||
if (temp == null) return 1; // 故障时写入1?协议未明确写故障,一般写有效值
|
|
||||||
int raw = (int) Math.round(temp * 2 + 64); |
|
||||||
// 限制范围 0~255,但协议中有效温度对应 raw 范围 4~? 不做严格限制
|
|
||||||
return Math.min(255, Math.max(0, raw)); |
|
||||||
} |
|
||||||
|
|
||||||
// TEMP2 解析:温度 = raw - 32,raw=1 表示故障
|
|
||||||
private static Integer parseTemp2(int raw) { |
|
||||||
if (raw == 1) return 1; |
|
||||||
return raw - 32; |
|
||||||
} |
|
||||||
|
|
||||||
// TEMP2 编码
|
|
||||||
private static int encodeTemp2(Integer temp) { |
|
||||||
if (temp == null) return 1; |
|
||||||
int raw = temp + 32; |
|
||||||
return Math.min(255, Math.max(0, raw)); |
|
||||||
} |
|
||||||
|
|
||||||
// 版本号解析:高8位类别版本,低8位主板版本
|
|
||||||
private static String parseVersion(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01AH 输入开关状态
|
|
||||||
private static String parseInputSwitchStatus(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01BH 水位开关状态
|
|
||||||
private static String parseWaterLevelSwitch(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01CH 输出1状态
|
|
||||||
private static String parseOutput1Status(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01DH 输出2状态
|
|
||||||
private static String parseOutput2Status(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01EH 输出3状态
|
|
||||||
private static String parseOutput3Status(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A01FH 机组信息
|
|
||||||
private static String parseDipSwitch(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// A020H 主板类别
|
|
||||||
private static String parseMainboardType(int value) { |
|
||||||
return String.valueOf(value); |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== 测试示例 ====================
|
|
||||||
public static void main(String[] args) { |
|
||||||
// 示例:解析 A000H 显示水温,原始值 110 -> 温度 (110-64)/2 = 23℃
|
|
||||||
System.out.println("显示水温: " + parse(ADDR_DISPLAY_WATER_TEMP, 110) + "℃"); |
|
||||||
System.out.println(ADDR_DISPLAY_WATER_TEMP); |
|
||||||
// 示例:解析 A007H 排气1温度,原始值 33 -> 33-32=1℃
|
|
||||||
System.out.println("排气1温度: " + parse(ADDR_EXHAUST1_TEMP, 33) + "℃"); |
|
||||||
// 示例:解析 B003H 运行模式,原始值 1 -> 制冷
|
|
||||||
System.out.println("运行模式: " + parse("A01D", 1)); |
|
||||||
|
|
||||||
// 编码示例:写恒温设置温度 25℃
|
|
||||||
int encoded = encode(ADDR_CONSTANT_TEMP_SET, 25); // 25+32=57
|
|
||||||
System.out.println("恒温设置温度 25℃ 编码为: " + encoded); |
|
||||||
// 写开关机:开机
|
|
||||||
encoded = encode(ADDR_ON_OFF, "开机"); |
|
||||||
System.out.println("开机编码: " + encoded); |
|
||||||
|
|
||||||
// 测试字符串地址传入
|
|
||||||
System.out.println("\n--- 测试字符串地址 ---"); |
|
||||||
System.out.println("显示水温: " + parse("A000", 110) + "℃"); |
|
||||||
System.out.println("运行模式: " + parse("B003", 1)); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,6 +1,6 @@ |
|||||||
spring: |
spring: |
||||||
profiles: |
profiles: |
||||||
active: prod |
active: dev |
||||||
mvc: |
mvc: |
||||||
pathmatch: |
pathmatch: |
||||||
matching-strategy: ant_path_matcher |
matching-strategy: ant_path_matcher |
||||||
|
|||||||
Loading…
Reference in new issue