Skip to content

Commit

Permalink
[daikin] Update channels immediately after a successful API command (o…
Browse files Browse the repository at this point in the history
…penhab#17149)

* [daikin] Update channels immediately after a successful API command

Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng authored and matchews committed Oct 18, 2024
1 parent 0737c99 commit 14eec3b
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
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;
Expand All @@ -33,7 +32,6 @@
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;
Expand Down Expand Up @@ -119,9 +117,7 @@ public ControlInfo getControlInfo() throws DaikinCommunicationException {

public boolean setControlInfo(ControlInfo info) throws DaikinCommunicationException {
Map<String, String> queryParams = info.getParamString();
String result = invoke(setControlInfoUri, queryParams);
Map<String, String> responseMap = InfoParser.parse(result);
return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK");
return isSuccessful(invoke(setControlInfoUri, queryParams));
}

public SensorInfo getSensorInfo() throws DaikinCommunicationException {
Expand All @@ -146,7 +142,7 @@ public EnergyInfoDayAndWeek getEnergyInfoDayAndWeek() throws DaikinCommunication
return EnergyInfoDayAndWeek.parse(response);
}

public void setSpecialMode(SpecialMode newMode) throws DaikinCommunicationException {
public boolean setSpecialMode(SpecialMode newMode) throws DaikinCommunicationException {
Map<String, String> queryParams = new HashMap<>();
if (newMode == SpecialMode.NORMAL) {
queryParams.put("set_spmode", "0");
Expand All @@ -160,17 +156,23 @@ public void setSpecialMode(SpecialMode newMode) throws DaikinCommunicationExcept
queryParams.put("spmode_kind", newMode.getValue());
}
String response = invoke(setSpecialModeUri, queryParams);
if (!response.contains("ret=OK")) {
if (isSuccessful(response)) {
return true;
} else {
logger.warn("Error setting special mode. Response: '{}'", response);
return false;
}
}

public void setStreamerMode(boolean state) throws DaikinCommunicationException {
public boolean setStreamerMode(boolean state) throws DaikinCommunicationException {
Map<String, String> queryParams = new HashMap<>();
queryParams.put("en_streamer", state ? "1" : "0");
String response = invoke(setSpecialModeUri, queryParams);
if (!response.contains("ret=OK")) {
if (isSuccessful(response)) {
return true;
} else {
logger.warn("Error setting streamer mode. Response: '{}'", response);
return false;
}
}

Expand All @@ -181,9 +183,7 @@ public DemandControl getDemandControl() throws DaikinCommunicationException {

public boolean setDemandControl(DemandControl info) throws DaikinCommunicationException {
Map<String, String> queryParams = info.getParamString();
String result = invoke(setDemandControlUri, queryParams);
Map<String, String> responseMap = InfoParser.parse(result);
return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK");
return isSuccessful(invoke(setDemandControlUri, queryParams));
}

// Daikin Airbase API
Expand All @@ -192,9 +192,9 @@ public AirbaseControlInfo getAirbaseControlInfo() throws DaikinCommunicationExce
return AirbaseControlInfo.parse(response);
}

public void setAirbaseControlInfo(AirbaseControlInfo info) throws DaikinCommunicationException {
public boolean setAirbaseControlInfo(AirbaseControlInfo info) throws DaikinCommunicationException {
Map<String, String> queryParams = info.getParamString();
invoke(setAirbaseControlInfoUri, queryParams);
return isSuccessful(invoke(setAirbaseControlInfoUri, queryParams));
}

public SensorInfo getAirbaseSensorInfo() throws DaikinCommunicationException {
Expand All @@ -217,9 +217,13 @@ public AirbaseZoneInfo getAirbaseZoneInfo() throws DaikinCommunicationException
return AirbaseZoneInfo.parse(response);
}

public void setAirbaseZoneInfo(AirbaseZoneInfo zoneinfo) throws DaikinCommunicationException {
public boolean setAirbaseZoneInfo(AirbaseZoneInfo zoneinfo) throws DaikinCommunicationException {
Map<String, String> queryParams = zoneinfo.getParamString();
invoke(setAirbaseZoneInfoUri, queryParams);
return isSuccessful(invoke(setAirbaseZoneInfoUri, queryParams));
}

private boolean isSuccessful(String response) {
return response.contains("ret=OK");
}

private String invoke(String uri) throws DaikinCommunicationException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public enum HomekitMode {
HEAT("heat"),
OFF("off");

private static final Logger LOGGER = LoggerFactory.getLogger(HomekitMode.class);
private final String value;

HomekitMode(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,25 @@ protected boolean handleCommandInternal(ChannelUID channelUID, Command command)
switch (channelUID.getId()) {
case DaikinBindingConstants.CHANNEL_AC_FAN_DIR:
if (command instanceof StringType stringCommand) {
changeFanDir(stringCommand.toString());
if (changeFanDir(stringCommand.toString())) {
updateState(channelUID, stringCommand);
}
return true;
}
break;
case DaikinBindingConstants.CHANNEL_AC_SPECIALMODE:
if (command instanceof StringType stringCommand) {
changeSpecialMode(stringCommand.toString());
if (changeSpecialMode(stringCommand.toString())) {
updateState(channelUID, stringCommand);
}
return true;
}
break;
case DaikinBindingConstants.CHANNEL_AC_STREAMER:
if (command instanceof OnOffType onOffCommand) {
changeStreamer(onOffCommand.equals(OnOffType.ON));
if (changeStreamer(onOffCommand.equals(OnOffType.ON))) {
updateState(channelUID, onOffCommand);
}
return true;
}
break;
Expand All @@ -216,13 +222,21 @@ protected boolean handleCommandInternal(ChannelUID channelUID, Command command)
break;
case DaikinBindingConstants.CHANNEL_AC_DEMAND_MAX_POWER:
if (command instanceof PercentType percentCommand) {
changeDemandMaxPower(percentCommand.intValue());
if (changeDemandMaxPower(percentCommand.intValue())) {
updateState(DaikinBindingConstants.CHANNEL_AC_DEMAND_MODE,
new StringType(DemandControlMode.MANUAL.name()));
updateState(channelUID, percentCommand);
}
return true;
}
break;
case DaikinBindingConstants.CHANNEL_AC_DEMAND_SCHEDULE:
if (command instanceof StringType stringCommand) {
changeDemandSchedule(stringCommand.toString());
if (changeDemandSchedule(stringCommand.toString())) {
updateState(DaikinBindingConstants.CHANNEL_AC_DEMAND_MODE,
new StringType(DemandControlMode.SCHEDULED.name()));
updateState(channelUID, stringCommand);
}
return true;
}
break;
Expand All @@ -231,27 +245,27 @@ protected boolean handleCommandInternal(ChannelUID channelUID, Command command)
}

@Override
protected void changePower(boolean power) throws DaikinCommunicationException {
protected boolean changePower(boolean power) throws DaikinCommunicationException {
ControlInfo info = webTargets.getControlInfo();
info.power = power;
webTargets.setControlInfo(info);
return webTargets.setControlInfo(info);
}

@Override
protected void changeSetPoint(double newTemperature) throws DaikinCommunicationException {
protected boolean changeSetPoint(double newTemperature) throws DaikinCommunicationException {
ControlInfo info = webTargets.getControlInfo();
info.temp = Optional.of(newTemperature);
webTargets.setControlInfo(info);
return webTargets.setControlInfo(info);
}

@Override
protected void changeMode(String mode) throws DaikinCommunicationException {
protected boolean changeMode(String mode) throws DaikinCommunicationException {
Mode newMode;
try {
newMode = Mode.valueOf(mode);
} catch (IllegalArgumentException ex) {
logger.warn("Invalid mode: {}. Valid values: {}", mode, Mode.values());
return;
return false;
}
ControlInfo info = webTargets.getControlInfo();
info.mode = newMode;
Expand All @@ -263,55 +277,58 @@ protected void changeMode(String mode) throws DaikinCommunicationException {
// 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)) {
accepted = webTargets.setControlInfo(info);
if (accepted) {
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");
}
}

return accepted;
}

@Override
protected void changeFanSpeed(String fanSpeed) throws DaikinCommunicationException {
protected boolean changeFanSpeed(String fanSpeed) throws DaikinCommunicationException {
FanSpeed newSpeed;
try {
newSpeed = FanSpeed.valueOf(fanSpeed);
} catch (IllegalArgumentException ex) {
logger.warn("Invalid fan speed: {}. Valid values: {}", fanSpeed, FanSpeed.values());
return;
return false;
}
ControlInfo info = webTargets.getControlInfo();
info.fanSpeed = newSpeed;
webTargets.setControlInfo(info);
return webTargets.setControlInfo(info);
}

protected void changeFanDir(String fanDir) throws DaikinCommunicationException {
protected boolean changeFanDir(String fanDir) throws DaikinCommunicationException {
FanMovement newMovement;
try {
newMovement = FanMovement.valueOf(fanDir);
} catch (IllegalArgumentException ex) {
logger.warn("Invalid fan direction: {}. Valid values: {}", fanDir, FanMovement.values());
return;
return false;
}
ControlInfo info = webTargets.getControlInfo();
info.fanMovement = newMovement;
webTargets.setControlInfo(info);
return webTargets.setControlInfo(info);
}

protected void changeSpecialMode(String specialMode) throws DaikinCommunicationException {
protected boolean changeSpecialMode(String specialMode) throws DaikinCommunicationException {
SpecialMode newMode;
try {
newMode = SpecialMode.valueOf(specialMode);
} catch (IllegalArgumentException e) {
logger.warn("Invalid specialmode: {}. Valid values: {}", specialMode, SpecialMode.values());
return;
return false;
}
webTargets.setSpecialMode(newMode);
return webTargets.setSpecialMode(newMode);
}

protected void changeStreamer(boolean streamerMode) throws DaikinCommunicationException {
webTargets.setStreamerMode(streamerMode);
protected boolean changeStreamer(boolean streamerMode) throws DaikinCommunicationException {
return webTargets.setStreamerMode(streamerMode);
}

protected void changeDemandMode(String mode) throws DaikinCommunicationException {
Expand All @@ -323,40 +340,54 @@ protected void changeDemandMode(String mode) throws DaikinCommunicationException
return;
}
DemandControl demandInfo = webTargets.getDemandControl();
boolean scheduleChanged = false;
boolean maxPowerChanged = false;
if (demandInfo.mode != newMode) {
if (newMode == DemandControlMode.SCHEDULED && savedDemandControlSchedule.isPresent()) {
// restore previously saved schedule
demandInfo.setSchedule(savedDemandControlSchedule.get());
scheduleChanged = true;
}

if (newMode == DemandControlMode.MANUAL && savedDemandControlMaxPower.isPresent()) {
// restore previously saved maxPower
demandInfo.maxPower = savedDemandControlMaxPower.get();
maxPowerChanged = true;
}
}
demandInfo.mode = newMode;
webTargets.setDemandControl(demandInfo);
if (webTargets.setDemandControl(demandInfo)) {
updateState(DaikinBindingConstants.CHANNEL_AC_DEMAND_MODE, new StringType(newMode.name()));
if (scheduleChanged) {
updateState(DaikinBindingConstants.CHANNEL_AC_DEMAND_SCHEDULE,
new StringType(savedDemandControlSchedule.get()));
}
if (maxPowerChanged) {
updateState(DaikinBindingConstants.CHANNEL_AC_DEMAND_MAX_POWER,
new PercentType(savedDemandControlMaxPower.get()));
}
}
}

protected void changeDemandMaxPower(int maxPower) throws DaikinCommunicationException {
protected boolean changeDemandMaxPower(int maxPower) throws DaikinCommunicationException {
DemandControl demandInfo = webTargets.getDemandControl();
demandInfo.mode = DemandControlMode.MANUAL;
demandInfo.maxPower = maxPower;
webTargets.setDemandControl(demandInfo);
savedDemandControlMaxPower = Optional.of(maxPower);
return webTargets.setDemandControl(demandInfo);
}

protected void changeDemandSchedule(String schedule) throws DaikinCommunicationException {
protected boolean changeDemandSchedule(String schedule) throws DaikinCommunicationException {
DemandControl demandInfo = webTargets.getDemandControl();
try {
demandInfo.setSchedule(schedule);
} catch (JsonSyntaxException e) {
logger.warn("Invalid schedule: {}. {}", schedule, e.getMessage());
return;
return false;
}
demandInfo.mode = DemandControlMode.SCHEDULED;
webTargets.setDemandControl(demandInfo);
savedDemandControlSchedule = Optional.of(demandInfo.getSchedule());
return webTargets.setDemandControl(demandInfo);
}

/**
Expand Down
Loading

0 comments on commit 14eec3b

Please sign in to comment.