优化红外除湿机控制逻辑

This commit is contained in:
BBIT-Kai
2026-08-10 10:47:25 +08:00
parent 4de70ff57a
commit 090b120365
3 changed files with 138 additions and 17 deletions
@@ -22,8 +22,10 @@ import com.example.iot_controlhost.utils.log.MyLog;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import android_serialport_api.SerialPortUtil; import android_serialport_api.SerialPortUtil;
@@ -80,6 +82,16 @@ public class RoomController {
* 485除湿机物理电源 * 485除湿机物理电源
*/ */
public static Dehumidifier485Relay dehumidifier485Relay = new Dehumidifier485Relay(DEVICE_NAME[17]); public static Dehumidifier485Relay dehumidifier485Relay = new Dehumidifier485Relay(DEVICE_NAME[17]);
/**
* 红外除湿机运行功率阈值。
* 待机时约2W,风机启动后约60-70W,压缩机启动后约300W。
*/
private static final double DEHUMIDIFIER_RUNNING_POWER = 50.0;
private static final int DEHUMIDIFIER_MISMATCH_CONFIRM_TIMES = 2;
private static int dehumidifierMismatchTimes;
private static Boolean lastDehumidifierMismatchTarget;
private static final Set<String> dehumidifierPollingLogKeys = new HashSet<>();
/** /**
* 加湿器 * 加湿器
*/ */
@@ -295,31 +307,29 @@ public class RoomController {
})); }));
} }
}); });
// 检查除湿机功率是否与除湿机物理电源状态匹配,时刻监测当前除湿机功率状态,使之与软件开关匹配 // 485除湿机保持原有5分钟检测逻辑。
// 防止出现软件界面中开启除湿器但实际上除湿器未开启(功率不足100W)的情况 if (RoomController.dehumidifier485Relay.isAvailable()) {
if (RoomController.dehumidifier.isAvailable() || RoomController.dehumidifier485Relay.isAvailable()) {
PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_DEHUMIDIFIER_STATUS, 60 * 5, () -> { PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_DEHUMIDIFIER_STATUS, 60 * 5, () -> {
if (RoomController.dehumidifier.isAvailable() && RoomController.dehumidifier.isPowerSupply() && RoomController.dehumidifier.getPower() < 100) { if (RoomController.dehumidifier485.isPowerSupply()
MyLog.controllerError("除湿机电源已开启但功率不足100W,现尝试再次开启除湿机红外电源");//红外开关是一样的指令 所以这里等于是重新发送
MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifier.setPowerSupply(true)));
} else if (RoomController.dehumidifier.isAvailable() && !RoomController.dehumidifier.isPowerSupply() && RoomController.dehumidifier.getPower() > 100) {
MyLog.controllerError("除湿机电源已关闭但功率大于100W,现尝试再次关闭除湿机红外电源");
MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifier.setPowerSupply(false)));
}
if (RoomController.dehumidifier485Relay.isAvailable()
&& RoomController.dehumidifier485.isPowerSupply()
&& RoomController.dehumidifier485Relay.getPower() < 100) { && RoomController.dehumidifier485Relay.getPower() < 100) {
MyLog.controllerError("485除湿机电源已开启但功率不足100W,现尝试再次开启485除湿机物理电源"); MyLog.controllerError("485除湿机电源已开启但功率不足100W,现尝试再次开启485除湿机物理电源");
MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifier485Relay.setPowerSupply(true))); MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(
} else if (RoomController.dehumidifier485Relay.isAvailable() () -> RoomController.dehumidifier485Relay.setPowerSupply(true)));
&& !RoomController.dehumidifier485.isPowerSupply() } else if (!RoomController.dehumidifier485.isPowerSupply()
&& RoomController.dehumidifier485Relay.getPower() > 100) { && RoomController.dehumidifier485Relay.getPower() > 100) {
MyLog.controllerError("485除湿机电源已关闭但功率大于100W,现尝试再次关闭485除湿机物理电源"); MyLog.controllerError("485除湿机电源已关闭但功率大于100W,现尝试再次关闭485除湿机物理电源");
MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifier485Relay.setPowerSupply(false))); MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(
() -> RoomController.dehumidifier485Relay.setPowerSupply(false)));
} }
}); });
} }
} }
// 检查除湿机功率是否与软件状态匹配。红外开关为同一条翻转指令,必须确认状态后才能补发。
if (RoomController.dehumidifier.isAvailable()) {
PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_INFRARED_DEHUMIDIFIER_STATUS, 60, () ->
MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(
new QueueIOTask(RoomController::checkInfraredDehumidifierStatus)));
}
//初始化新线程,时刻监测当前空调红外状态,以使得物理开关与之匹配 //初始化新线程,时刻监测当前空调红外状态,以使得物理开关与之匹配
PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_CONTROLLER_STATE_CHECK_AIR, RoomSetting.getTimeOfAirStopRelay(), () -> { PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_CONTROLLER_STATE_CHECK_AIR, RoomSetting.getTimeOfAirStopRelay(), () -> {
// MyLog.test("空调后台线程:现检查是否需要关闭空调物理电源"); // MyLog.test("空调后台线程:现检查是否需要关闭空调物理电源");
@@ -380,6 +390,116 @@ public class RoomController {
public static boolean doNotNeedDelayCloseDehumidifier = true; public static boolean doNotNeedDelayCloseDehumidifier = true;
public static boolean doNotNeedDelayCloseDehumidifier485 = true; public static boolean doNotNeedDelayCloseDehumidifier485 = true;
/**
* 根据分路功率或总功率校验红外除湿机真实状态。
*/
private static void checkInfraredDehumidifierStatus() {
if (!RoomController.dehumidifier.isAvailable()) {
resetDehumidifierMismatch();
return;
}
boolean useBranchPower = RoomController.relay.getModel().equals(RoomController.relay.getModels()[2]);
double power;
String powerSource;
if (useBranchPower) {
if (!RoomController.dehumidifier.collectSensorData()) {
resetDehumidifierMismatchCount();
logDehumidifierPollingOnce("branch-collect-failed", "红外除湿机状态检测:BBIT继电器分路功率采集失败,本轮不判断状态", true);
return;
}
power = RoomController.dehumidifier.getPower();
powerSource = "BBIT继电器分路功率";
} else {
if (!RoomSensor.consumptionSensor.isAvailable()) {
resetDehumidifierMismatchCount();
logDehumidifierPollingOnce("total-unavailable", "红外除湿机状态检测:无BBIT继电器分路功率,且总能耗传感器不可用,本轮不判断状态", true);
return;
}
if (hasOtherPoweredDeviceForDehumidifierCheck()) {
resetDehumidifierMismatchCount();
logDehumidifierPollingOnce("other-device-running", "红外除湿机状态检测:其他设备正在运行,无法从总功率中分离除湿机功率,本轮不判断状态", false);
return;
}
if (!RoomSensor.consumptionSensor.collectSensorData(
RoomSensor.consumptionSensor.getModel(), RoomSensor.consumptionSensor.getAddress())) {
resetDehumidifierMismatchCount();
logDehumidifierPollingOnce("total-collect-failed", "红外除湿机状态检测:总能耗功率采集失败,本轮不判断状态", true);
return;
}
power = RoomSensor.consumptionSensor.getPower();
powerSource = "总能耗功率";
}
boolean targetState = RoomController.dehumidifier.isPowerSupply();
boolean actualState = power > DEHUMIDIFIER_RUNNING_POWER;
if (targetState == actualState) {
if (lastDehumidifierMismatchTarget != null) {
MyLog.controller("红外除湿机状态恢复一致:目标=" + formatPowerState(targetState)
+ "" + powerSource + "=" + power + "W");
}
resetDehumidifierMismatch();
return;
}
if (lastDehumidifierMismatchTarget == null || lastDehumidifierMismatchTarget != targetState) {
dehumidifierMismatchTimes = 0;
lastDehumidifierMismatchTarget = targetState;
dehumidifierPollingLogKeys.clear();
}
dehumidifierMismatchTimes++;
logDehumidifierPollingOnce("mismatch-" + targetState,
"红外除湿机状态不一致:目标=" + formatPowerState(targetState)
+ ",检测=" + formatPowerState(actualState) + "" + powerSource + "=" + power
+ "W,将连续确认" + DEHUMIDIFIER_MISMATCH_CONFIRM_TIMES + "次后纠正", true);
if (dehumidifierMismatchTimes < DEHUMIDIFIER_MISMATCH_CONFIRM_TIMES) {
return;
}
boolean result = RoomController.dehumidifier.setPowerSupply(targetState);
logDehumidifierPollingOnce("correct-" + targetState + "-" + result,
"红外除湿机状态纠正:重新发送" + formatPowerState(targetState) + "指令,结果="
+ (result ? "成功" : "失败") + ",纠正前" + powerSource + "=" + power + "W", !result);
dehumidifierMismatchTimes = 0;
}
/**
* 使用总能耗功率时,只有除湿机之外的设备均未开启,功率才可归属于除湿机。
*/
private static boolean hasOtherPoweredDeviceForDehumidifierCheck() {
for (Relay relayDevice : RoomController.getAllAvailableRelays()) {
if (relayDevice != RoomController.dehumidifier && relayDevice.isPowerSupply()) {
return true;
}
}
return RoomController.dehumidifier485.isAvailable() && RoomController.dehumidifier485.isPowerSupply();
}
private static void resetDehumidifierMismatchCount() {
dehumidifierMismatchTimes = 0;
}
private static void resetDehumidifierMismatch() {
dehumidifierMismatchTimes = 0;
lastDehumidifierMismatchTarget = null;
dehumidifierPollingLogKeys.clear();
}
private static void logDehumidifierPollingOnce(String key, String message, boolean error) {
if (!dehumidifierPollingLogKeys.add(key)) {
return;
}
if (error) {
MyLog.controllerError(message);
} else {
MyLog.controller(message);
}
}
private static String formatPowerState(boolean state) {
return state ? "开启" : "关闭";
}
public static void closeAllControllers() { public static void closeAllControllers() {
List<Relay> relays = RoomController.getAllAvailableRelays(); List<Relay> relays = RoomController.getAllAvailableRelays();
MyInfraredUtils.getInstances().setPowerSupply(false); MyInfraredUtils.getInstances().setPowerSupply(false);
@@ -233,7 +233,7 @@ public class RoomSensor {
return 0.0; return 0.0;
} }
return sumOfHumidities / numberOfEnabledSensors; return Math.round(sumOfHumidities / numberOfEnabledSensors * 10.0) / 10.0;
} }
/** /**
* 获取叠加校准偏差后的室内平均湿度,供界面显示和上报使用。 * 获取叠加校准偏差后的室内平均湿度,供界面显示和上报使用。
@@ -60,6 +60,7 @@ public class RxTag {
* 持续检测除湿机工作状态 * 持续检测除湿机工作状态
*/ */
public static final String TAG_DEHUMIDIFIER_STATUS = "TAG_DEHUMIDIFIER_STATUS"; public static final String TAG_DEHUMIDIFIER_STATUS = "TAG_DEHUMIDIFIER_STATUS";
public static final String TAG_INFRARED_DEHUMIDIFIER_STATUS = "TAG_INFRARED_DEHUMIDIFIER_STATUS";
/** /**
* 持续判断是否注册 * 持续判断是否注册
*/ */