# 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
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;
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;
return ControlInfo.parse(response);
}
- public void setControlInfo(ControlInfo info) throws DaikinCommunicationException {
+ public boolean setControlInfo(ControlInfo info) throws DaikinCommunicationException {
Map<String, String> queryParams = info.getParamString();
- invoke(setControlInfoUri, queryParams);
+ String result = invoke(setControlInfoUri, queryParams);
+ Map<String, String> responseMap = InfoParser.parse(result);
+ return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK");
}
public SensorInfo getSensorInfo() throws DaikinCommunicationException {
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<Double> 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<Integer> targetHumidity = Optional.empty();
public AdvancedMode advancedMode = AdvancedMode.UNKNOWN;
public boolean separatedDirectionParams = false;
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);
public Map<String, String> getParamString() {
Map<String, String> 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",
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),
public class DaikinAcUnitHandler extends DaikinBaseHandler {
private final Logger logger = LoggerFactory.getLogger(DaikinAcUnitHandler.class);
+ private Optional<Integer> autoModeValue = Optional.empty();
+
public DaikinAcUnitHandler(Thing thing, DaikinDynamicStateDescriptionProvider stateDescriptionProvider,
@Nullable HttpClient httpClient) {
super(thing, stateDescriptionProvider, httpClient);
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);
}
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