From 5e1f24c54fd21a85854265bdc27eb0e9236da1c7 Mon Sep 17 00:00:00 2001 From: jimtng <2554958+jimtng@users.noreply.github.com> Date: Wed, 30 Aug 2023 02:37:01 +1000 Subject: [PATCH] [daikin] Support BRP069A81 adapter (#15456) * [daikin] Support BRP069A81 adapter auto mode=1 * [daikin] Support Auto mode=7 Signed-off-by: Jimmy Tanagra --- bundles/org.openhab.binding.daikin/README.md | 10 +++++++--- .../daikin/internal/DaikinWebTargets.java | 8 ++++++-- .../daikin/internal/api/ControlInfo.java | 13 ++++++++++--- .../binding/daikin/internal/api/Enums.java | 2 ++ .../internal/handler/DaikinAcUnitHandler.java | 19 ++++++++++++++++++- 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/bundles/org.openhab.binding.daikin/README.md b/bundles/org.openhab.binding.daikin/README.md index 02dccd408..1145fb476 100644 --- a/bundles/org.openhab.binding.daikin/README.md +++ b/bundles/org.openhab.binding.daikin/README.md @@ -1,12 +1,16 @@ # Daikin Binding The Daikin binding allows you to control your Daikin air conditioning units with openHAB. -In order to do so, your Daikin air conditioning unit must have a BRP072A42, BRP072C42 or BRP15B61 WiFi adapter installed. + +In order to do so, your Daikin air conditioning unit must have a supported Wi-Fi adapter installed. +This may work with the older KRP series of wired adapters, but has not been tested with them. ## Supported Things -Daikin air conditioning units with a BRP069B41, BRP072A42, BRP072C42 or BRP15B61 installed. -This may work with the older KRP series of wired adapters, but has not been tested with them. +| Thing | Daikin Wi-Fi Adapter Model | +| ----------------- | ------------------------------------------ | +| `ac_unit` | BRP069A81, BRP069B41, BRP072A42, BRP072C42 | +| `airbase_ac_unit` | BRP15B61 | ## Discovery diff --git a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/DaikinWebTargets.java b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/DaikinWebTargets.java index af0e2c9cd..38c61ce7c 100644 --- a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/DaikinWebTargets.java +++ b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/DaikinWebTargets.java @@ -15,6 +15,7 @@ package org.openhab.binding.daikin.internal; import java.io.EOFException; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -31,6 +32,7 @@ import org.openhab.binding.daikin.internal.api.ControlInfo; import org.openhab.binding.daikin.internal.api.EnergyInfoDayAndWeek; import org.openhab.binding.daikin.internal.api.EnergyInfoYear; import org.openhab.binding.daikin.internal.api.Enums.SpecialMode; +import org.openhab.binding.daikin.internal.api.InfoParser; import org.openhab.binding.daikin.internal.api.SensorInfo; import org.openhab.binding.daikin.internal.api.airbase.AirbaseBasicInfo; import org.openhab.binding.daikin.internal.api.airbase.AirbaseControlInfo; @@ -110,9 +112,11 @@ public class DaikinWebTargets { return ControlInfo.parse(response); } - public void setControlInfo(ControlInfo info) throws DaikinCommunicationException { + public boolean setControlInfo(ControlInfo info) throws DaikinCommunicationException { Map queryParams = info.getParamString(); - invoke(setControlInfoUri, queryParams); + String result = invoke(setControlInfoUri, queryParams); + Map responseMap = InfoParser.parse(result); + return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK"); } public SensorInfo getSensorInfo() throws DaikinCommunicationException { diff --git a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/ControlInfo.java b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/ControlInfo.java index 3ed1bc1b8..b12c1706c 100644 --- a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/ControlInfo.java +++ b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/ControlInfo.java @@ -38,12 +38,14 @@ public class ControlInfo { public String ret = ""; public boolean power = false; + // Store the accepted auto mode for later use. + public int autoModeValue = Mode.AUTO.getValue(); public Mode mode = Mode.AUTO; - /** Degrees in Celsius. */ + // Degrees in Celsius. public Optional temp = Optional.empty(); public FanSpeed fanSpeed = FanSpeed.AUTO; public FanMovement fanMovement = FanMovement.STOPPED; - /* Not supported by all units. Sets the target humidity for dehumidifying. */ + // Not supported by all units. Sets the target humidity for dehumidifying. public Optional targetHumidity = Optional.empty(); public AdvancedMode advancedMode = AdvancedMode.UNKNOWN; public boolean separatedDirectionParams = false; @@ -61,6 +63,11 @@ public class ControlInfo { info.power = "1".equals(responseMap.get("pow")); info.mode = Optional.ofNullable(responseMap.get("mode")).flatMap(value -> InfoParser.parseInt(value)) .map(value -> Mode.fromValue(value)).orElse(Mode.AUTO); + // Normalize AUTO1 and AUTO7 to AUTO + if (info.mode == Mode.AUTO1 || info.mode == Mode.AUTO7) { + info.autoModeValue = info.mode.getValue(); + info.mode = Mode.AUTO; + } info.temp = Optional.ofNullable(responseMap.get("stemp")).flatMap(value -> InfoParser.parseDouble(value)); info.fanSpeed = Optional.ofNullable(responseMap.get("f_rate")).map(value -> FanSpeed.fromValue(value)) .orElse(FanSpeed.AUTO); @@ -90,7 +97,7 @@ public class ControlInfo { public Map getParamString() { Map params = new HashMap<>(); params.put("pow", power ? "1" : "0"); - params.put("mode", Integer.toString(mode.getValue())); + params.put("mode", Integer.toString(mode == Mode.AUTO ? autoModeValue : mode.getValue())); params.put("f_rate", fanSpeed.getValue()); if (separatedDirectionParams) { params.put("f_dir_lr", diff --git a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/Enums.java b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/Enums.java index 6799f6c02..07bd1026d 100644 --- a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/Enums.java +++ b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/api/Enums.java @@ -28,6 +28,8 @@ public class Enums { public enum Mode { UNKNOWN(-1), AUTO(0), + AUTO1(1), // BRP069A81 only accepts mode=1 for AUTO mode. 0 and 7 are rejected. + AUTO7(7), // Some adapters may return 7 as auto (heating) DEHUMIDIFIER(2), COLD(3), HEAT(4), diff --git a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/handler/DaikinAcUnitHandler.java b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/handler/DaikinAcUnitHandler.java index 698b0b39b..4f3f66437 100644 --- a/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/handler/DaikinAcUnitHandler.java +++ b/bundles/org.openhab.binding.daikin/src/main/java/org/openhab/binding/daikin/internal/handler/DaikinAcUnitHandler.java @@ -57,6 +57,8 @@ import org.slf4j.LoggerFactory; public class DaikinAcUnitHandler extends DaikinBaseHandler { private final Logger logger = LoggerFactory.getLogger(DaikinAcUnitHandler.class); + private Optional autoModeValue = Optional.empty(); + public DaikinAcUnitHandler(Thing thing, DaikinDynamicStateDescriptionProvider stateDescriptionProvider, @Nullable HttpClient httpClient) { super(thing, stateDescriptionProvider, httpClient); @@ -68,6 +70,7 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler { if (!"OK".equals(controlInfo.ret)) { throw new DaikinCommunicationException("Invalid response from host"); } + updateState(DaikinBindingConstants.CHANNEL_AC_POWER, OnOffType.from(controlInfo.power)); updateTemperatureChannel(DaikinBindingConstants.CHANNEL_AC_TEMP, controlInfo.temp); @@ -202,7 +205,21 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler { } ControlInfo info = webTargets.getControlInfo(); info.mode = newMode; - webTargets.setControlInfo(info); + if (autoModeValue.isPresent()) { + info.autoModeValue = autoModeValue.get(); + } + boolean accepted = webTargets.setControlInfo(info); + + // If mode=0 is not accepted try AUTO1 (mode=1) + if (!accepted && newMode == Mode.AUTO && autoModeValue.isEmpty()) { + info.autoModeValue = Mode.AUTO1.getValue(); + if (webTargets.setControlInfo(info)) { + autoModeValue = Optional.of(info.autoModeValue); + logger.debug("AUTO uses mode={}", info.autoModeValue); + } else { + logger.warn("AUTO mode not accepted with mode=0 or mode=1"); + } + } } @Override