From 090b120365a1ba2c38aac13c2b4994a3454a5f08 Mon Sep 17 00:00:00 2001 From: BBIT-Kai <2911862937@qq.com> Date: Mon, 10 Aug 2026 10:47:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BA=A2=E5=A4=96=E9=99=A4?= =?UTF-8?q?=E6=B9=BF=E6=9C=BA=E6=8E=A7=E5=88=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/global/RoomController.java | 152 ++++++++++++++++-- .../utils/global/RoomSensor.java | 2 +- .../iot_controlhost/utils/global/RxTag.java | 1 + 3 files changed, 138 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/example/iot_controlhost/utils/global/RoomController.java b/app/src/main/java/com/example/iot_controlhost/utils/global/RoomController.java index 0cd77d1..360eac8 100644 --- a/app/src/main/java/com/example/iot_controlhost/utils/global/RoomController.java +++ b/app/src/main/java/com/example/iot_controlhost/utils/global/RoomController.java @@ -22,8 +22,10 @@ import com.example.iot_controlhost.utils.log.MyLog; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import android_serialport_api.SerialPortUtil; @@ -80,6 +82,16 @@ public class RoomController { * 485除湿机物理电源 */ 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 dehumidifierPollingLogKeys = new HashSet<>(); /** * 加湿器 */ @@ -295,31 +307,29 @@ public class RoomController { })); } }); - // 检查除湿机功率是否与除湿机物理电源状态匹配,时刻监测当前除湿机功率状态,使之与软件开关匹配 - // 防止出现软件界面中开启除湿器但实际上除湿器未开启(功率不足100W)的情况 - if (RoomController.dehumidifier.isAvailable() || RoomController.dehumidifier485Relay.isAvailable()) { + // 485除湿机保持原有5分钟检测逻辑。 + if (RoomController.dehumidifier485Relay.isAvailable()) { PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_DEHUMIDIFIER_STATUS, 60 * 5, () -> { - 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(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() + if (RoomController.dehumidifier485.isPowerSupply() && RoomController.dehumidifier485Relay.getPower() < 100) { MyLog.controllerError("485除湿机电源已开启但功率不足100W,现尝试再次开启485除湿机物理电源"); - MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifier485Relay.setPowerSupply(true))); - } else if (RoomController.dehumidifier485Relay.isAvailable() - && !RoomController.dehumidifier485.isPowerSupply() + MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask( + () -> RoomController.dehumidifier485Relay.setPowerSupply(true))); + } else if (!RoomController.dehumidifier485.isPowerSupply() && RoomController.dehumidifier485Relay.getPower() > 100) { 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(), () -> { // MyLog.test("空调后台线程:现检查是否需要关闭空调物理电源"); @@ -380,6 +390,116 @@ public class RoomController { public static boolean doNotNeedDelayCloseDehumidifier = 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() { List relays = RoomController.getAllAvailableRelays(); MyInfraredUtils.getInstances().setPowerSupply(false); diff --git a/app/src/main/java/com/example/iot_controlhost/utils/global/RoomSensor.java b/app/src/main/java/com/example/iot_controlhost/utils/global/RoomSensor.java index f644f31..adee8e1 100644 --- a/app/src/main/java/com/example/iot_controlhost/utils/global/RoomSensor.java +++ b/app/src/main/java/com/example/iot_controlhost/utils/global/RoomSensor.java @@ -233,7 +233,7 @@ public class RoomSensor { return 0.0; } - return sumOfHumidities / numberOfEnabledSensors; + return Math.round(sumOfHumidities / numberOfEnabledSensors * 10.0) / 10.0; } /** * 获取叠加校准偏差后的室内平均湿度,供界面显示和上报使用。 diff --git a/app/src/main/java/com/example/iot_controlhost/utils/global/RxTag.java b/app/src/main/java/com/example/iot_controlhost/utils/global/RxTag.java index 8d28ab6..a16eff6 100644 --- a/app/src/main/java/com/example/iot_controlhost/utils/global/RxTag.java +++ b/app/src/main/java/com/example/iot_controlhost/utils/global/RxTag.java @@ -60,6 +60,7 @@ public class RxTag { * 持续检测除湿机工作状态 */ public static final String TAG_DEHUMIDIFIER_STATUS = "TAG_DEHUMIDIFIER_STATUS"; + public static final String TAG_INFRARED_DEHUMIDIFIER_STATUS = "TAG_INFRARED_DEHUMIDIFIER_STATUS"; /** * 持续判断是否注册 */