mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-27 07:41:39 +01:00
[daikin] Update channels immediately after a successful API command (#17149)
* [daikin] Update channels immediately after a successful API command Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
parent
8725dcbe28
commit
198b9b184d
@ -15,7 +15,6 @@ package org.openhab.binding.daikin.internal;
|
|||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
@ -33,7 +32,6 @@ import org.openhab.binding.daikin.internal.api.DemandControl;
|
|||||||
import org.openhab.binding.daikin.internal.api.EnergyInfoDayAndWeek;
|
import org.openhab.binding.daikin.internal.api.EnergyInfoDayAndWeek;
|
||||||
import org.openhab.binding.daikin.internal.api.EnergyInfoYear;
|
import org.openhab.binding.daikin.internal.api.EnergyInfoYear;
|
||||||
import org.openhab.binding.daikin.internal.api.Enums.SpecialMode;
|
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.SensorInfo;
|
||||||
import org.openhab.binding.daikin.internal.api.airbase.AirbaseBasicInfo;
|
import org.openhab.binding.daikin.internal.api.airbase.AirbaseBasicInfo;
|
||||||
import org.openhab.binding.daikin.internal.api.airbase.AirbaseControlInfo;
|
import org.openhab.binding.daikin.internal.api.airbase.AirbaseControlInfo;
|
||||||
@ -119,9 +117,7 @@ public class DaikinWebTargets {
|
|||||||
|
|
||||||
public boolean setControlInfo(ControlInfo info) throws DaikinCommunicationException {
|
public boolean setControlInfo(ControlInfo info) throws DaikinCommunicationException {
|
||||||
Map<String, String> queryParams = info.getParamString();
|
Map<String, String> queryParams = info.getParamString();
|
||||||
String result = invoke(setControlInfoUri, queryParams);
|
return isSuccessful(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 SensorInfo getSensorInfo() throws DaikinCommunicationException {
|
||||||
@ -146,7 +142,7 @@ public class DaikinWebTargets {
|
|||||||
return EnergyInfoDayAndWeek.parse(response);
|
return EnergyInfoDayAndWeek.parse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpecialMode(SpecialMode newMode) throws DaikinCommunicationException {
|
public boolean setSpecialMode(SpecialMode newMode) throws DaikinCommunicationException {
|
||||||
Map<String, String> queryParams = new HashMap<>();
|
Map<String, String> queryParams = new HashMap<>();
|
||||||
if (newMode == SpecialMode.NORMAL) {
|
if (newMode == SpecialMode.NORMAL) {
|
||||||
queryParams.put("set_spmode", "0");
|
queryParams.put("set_spmode", "0");
|
||||||
@ -160,17 +156,23 @@ public class DaikinWebTargets {
|
|||||||
queryParams.put("spmode_kind", newMode.getValue());
|
queryParams.put("spmode_kind", newMode.getValue());
|
||||||
}
|
}
|
||||||
String response = invoke(setSpecialModeUri, queryParams);
|
String response = invoke(setSpecialModeUri, queryParams);
|
||||||
if (!response.contains("ret=OK")) {
|
if (isSuccessful(response)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
logger.warn("Error setting special mode. Response: '{}'", response);
|
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<>();
|
Map<String, String> queryParams = new HashMap<>();
|
||||||
queryParams.put("en_streamer", state ? "1" : "0");
|
queryParams.put("en_streamer", state ? "1" : "0");
|
||||||
String response = invoke(setSpecialModeUri, queryParams);
|
String response = invoke(setSpecialModeUri, queryParams);
|
||||||
if (!response.contains("ret=OK")) {
|
if (isSuccessful(response)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
logger.warn("Error setting streamer mode. Response: '{}'", response);
|
logger.warn("Error setting streamer mode. Response: '{}'", response);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,9 +183,7 @@ public class DaikinWebTargets {
|
|||||||
|
|
||||||
public boolean setDemandControl(DemandControl info) throws DaikinCommunicationException {
|
public boolean setDemandControl(DemandControl info) throws DaikinCommunicationException {
|
||||||
Map<String, String> queryParams = info.getParamString();
|
Map<String, String> queryParams = info.getParamString();
|
||||||
String result = invoke(setDemandControlUri, queryParams);
|
return isSuccessful(invoke(setDemandControlUri, queryParams));
|
||||||
Map<String, String> responseMap = InfoParser.parse(result);
|
|
||||||
return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daikin Airbase API
|
// Daikin Airbase API
|
||||||
@ -192,9 +192,9 @@ public class DaikinWebTargets {
|
|||||||
return AirbaseControlInfo.parse(response);
|
return AirbaseControlInfo.parse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAirbaseControlInfo(AirbaseControlInfo info) throws DaikinCommunicationException {
|
public boolean setAirbaseControlInfo(AirbaseControlInfo info) throws DaikinCommunicationException {
|
||||||
Map<String, String> queryParams = info.getParamString();
|
Map<String, String> queryParams = info.getParamString();
|
||||||
invoke(setAirbaseControlInfoUri, queryParams);
|
return isSuccessful(invoke(setAirbaseControlInfoUri, queryParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SensorInfo getAirbaseSensorInfo() throws DaikinCommunicationException {
|
public SensorInfo getAirbaseSensorInfo() throws DaikinCommunicationException {
|
||||||
@ -217,9 +217,13 @@ public class DaikinWebTargets {
|
|||||||
return AirbaseZoneInfo.parse(response);
|
return AirbaseZoneInfo.parse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAirbaseZoneInfo(AirbaseZoneInfo zoneinfo) throws DaikinCommunicationException {
|
public boolean setAirbaseZoneInfo(AirbaseZoneInfo zoneinfo) throws DaikinCommunicationException {
|
||||||
Map<String, String> queryParams = zoneinfo.getParamString();
|
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 {
|
private String invoke(String uri) throws DaikinCommunicationException {
|
||||||
|
@ -129,7 +129,6 @@ public class Enums {
|
|||||||
HEAT("heat"),
|
HEAT("heat"),
|
||||||
OFF("off");
|
OFF("off");
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HomekitMode.class);
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
HomekitMode(String value) {
|
HomekitMode(String value) {
|
||||||
|
@ -192,19 +192,25 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler {
|
|||||||
switch (channelUID.getId()) {
|
switch (channelUID.getId()) {
|
||||||
case DaikinBindingConstants.CHANNEL_AC_FAN_DIR:
|
case DaikinBindingConstants.CHANNEL_AC_FAN_DIR:
|
||||||
if (command instanceof StringType stringCommand) {
|
if (command instanceof StringType stringCommand) {
|
||||||
changeFanDir(stringCommand.toString());
|
if (changeFanDir(stringCommand.toString())) {
|
||||||
|
updateState(channelUID, stringCommand);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_SPECIALMODE:
|
case DaikinBindingConstants.CHANNEL_AC_SPECIALMODE:
|
||||||
if (command instanceof StringType stringCommand) {
|
if (command instanceof StringType stringCommand) {
|
||||||
changeSpecialMode(stringCommand.toString());
|
if (changeSpecialMode(stringCommand.toString())) {
|
||||||
|
updateState(channelUID, stringCommand);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_STREAMER:
|
case DaikinBindingConstants.CHANNEL_AC_STREAMER:
|
||||||
if (command instanceof OnOffType onOffCommand) {
|
if (command instanceof OnOffType onOffCommand) {
|
||||||
changeStreamer(onOffCommand.equals(OnOffType.ON));
|
if (changeStreamer(onOffCommand.equals(OnOffType.ON))) {
|
||||||
|
updateState(channelUID, onOffCommand);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -216,13 +222,21 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler {
|
|||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_DEMAND_MAX_POWER:
|
case DaikinBindingConstants.CHANNEL_AC_DEMAND_MAX_POWER:
|
||||||
if (command instanceof PercentType percentCommand) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_DEMAND_SCHEDULE:
|
case DaikinBindingConstants.CHANNEL_AC_DEMAND_SCHEDULE:
|
||||||
if (command instanceof StringType stringCommand) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -231,27 +245,27 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changePower(boolean power) throws DaikinCommunicationException {
|
protected boolean changePower(boolean power) throws DaikinCommunicationException {
|
||||||
ControlInfo info = webTargets.getControlInfo();
|
ControlInfo info = webTargets.getControlInfo();
|
||||||
info.power = power;
|
info.power = power;
|
||||||
webTargets.setControlInfo(info);
|
return webTargets.setControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeSetPoint(double newTemperature) throws DaikinCommunicationException {
|
protected boolean changeSetPoint(double newTemperature) throws DaikinCommunicationException {
|
||||||
ControlInfo info = webTargets.getControlInfo();
|
ControlInfo info = webTargets.getControlInfo();
|
||||||
info.temp = Optional.of(newTemperature);
|
info.temp = Optional.of(newTemperature);
|
||||||
webTargets.setControlInfo(info);
|
return webTargets.setControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeMode(String mode) throws DaikinCommunicationException {
|
protected boolean changeMode(String mode) throws DaikinCommunicationException {
|
||||||
Mode newMode;
|
Mode newMode;
|
||||||
try {
|
try {
|
||||||
newMode = Mode.valueOf(mode);
|
newMode = Mode.valueOf(mode);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
logger.warn("Invalid mode: {}. Valid values: {}", mode, Mode.values());
|
logger.warn("Invalid mode: {}. Valid values: {}", mode, Mode.values());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
ControlInfo info = webTargets.getControlInfo();
|
ControlInfo info = webTargets.getControlInfo();
|
||||||
info.mode = newMode;
|
info.mode = newMode;
|
||||||
@ -263,55 +277,58 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler {
|
|||||||
// If mode=0 is not accepted try AUTO1 (mode=1)
|
// If mode=0 is not accepted try AUTO1 (mode=1)
|
||||||
if (!accepted && newMode == Mode.AUTO && autoModeValue.isEmpty()) {
|
if (!accepted && newMode == Mode.AUTO && autoModeValue.isEmpty()) {
|
||||||
info.autoModeValue = Mode.AUTO1.getValue();
|
info.autoModeValue = Mode.AUTO1.getValue();
|
||||||
if (webTargets.setControlInfo(info)) {
|
accepted = webTargets.setControlInfo(info);
|
||||||
|
if (accepted) {
|
||||||
autoModeValue = Optional.of(info.autoModeValue);
|
autoModeValue = Optional.of(info.autoModeValue);
|
||||||
logger.debug("AUTO uses mode={}", info.autoModeValue);
|
logger.debug("AUTO uses mode={}", info.autoModeValue);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("AUTO mode not accepted with mode=0 or mode=1");
|
logger.warn("AUTO mode not accepted with mode=0 or mode=1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return accepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeFanSpeed(String fanSpeed) throws DaikinCommunicationException {
|
protected boolean changeFanSpeed(String fanSpeed) throws DaikinCommunicationException {
|
||||||
FanSpeed newSpeed;
|
FanSpeed newSpeed;
|
||||||
try {
|
try {
|
||||||
newSpeed = FanSpeed.valueOf(fanSpeed);
|
newSpeed = FanSpeed.valueOf(fanSpeed);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
logger.warn("Invalid fan speed: {}. Valid values: {}", fanSpeed, FanSpeed.values());
|
logger.warn("Invalid fan speed: {}. Valid values: {}", fanSpeed, FanSpeed.values());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
ControlInfo info = webTargets.getControlInfo();
|
ControlInfo info = webTargets.getControlInfo();
|
||||||
info.fanSpeed = newSpeed;
|
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;
|
FanMovement newMovement;
|
||||||
try {
|
try {
|
||||||
newMovement = FanMovement.valueOf(fanDir);
|
newMovement = FanMovement.valueOf(fanDir);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
logger.warn("Invalid fan direction: {}. Valid values: {}", fanDir, FanMovement.values());
|
logger.warn("Invalid fan direction: {}. Valid values: {}", fanDir, FanMovement.values());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
ControlInfo info = webTargets.getControlInfo();
|
ControlInfo info = webTargets.getControlInfo();
|
||||||
info.fanMovement = newMovement;
|
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;
|
SpecialMode newMode;
|
||||||
try {
|
try {
|
||||||
newMode = SpecialMode.valueOf(specialMode);
|
newMode = SpecialMode.valueOf(specialMode);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
logger.warn("Invalid specialmode: {}. Valid values: {}", specialMode, SpecialMode.values());
|
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 {
|
protected boolean changeStreamer(boolean streamerMode) throws DaikinCommunicationException {
|
||||||
webTargets.setStreamerMode(streamerMode);
|
return webTargets.setStreamerMode(streamerMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void changeDemandMode(String mode) throws DaikinCommunicationException {
|
protected void changeDemandMode(String mode) throws DaikinCommunicationException {
|
||||||
@ -323,40 +340,54 @@ public class DaikinAcUnitHandler extends DaikinBaseHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DemandControl demandInfo = webTargets.getDemandControl();
|
DemandControl demandInfo = webTargets.getDemandControl();
|
||||||
|
boolean scheduleChanged = false;
|
||||||
|
boolean maxPowerChanged = false;
|
||||||
if (demandInfo.mode != newMode) {
|
if (demandInfo.mode != newMode) {
|
||||||
if (newMode == DemandControlMode.SCHEDULED && savedDemandControlSchedule.isPresent()) {
|
if (newMode == DemandControlMode.SCHEDULED && savedDemandControlSchedule.isPresent()) {
|
||||||
// restore previously saved schedule
|
// restore previously saved schedule
|
||||||
demandInfo.setSchedule(savedDemandControlSchedule.get());
|
demandInfo.setSchedule(savedDemandControlSchedule.get());
|
||||||
|
scheduleChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newMode == DemandControlMode.MANUAL && savedDemandControlMaxPower.isPresent()) {
|
if (newMode == DemandControlMode.MANUAL && savedDemandControlMaxPower.isPresent()) {
|
||||||
// restore previously saved maxPower
|
// restore previously saved maxPower
|
||||||
demandInfo.maxPower = savedDemandControlMaxPower.get();
|
demandInfo.maxPower = savedDemandControlMaxPower.get();
|
||||||
|
maxPowerChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
demandInfo.mode = newMode;
|
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();
|
DemandControl demandInfo = webTargets.getDemandControl();
|
||||||
demandInfo.mode = DemandControlMode.MANUAL;
|
demandInfo.mode = DemandControlMode.MANUAL;
|
||||||
demandInfo.maxPower = maxPower;
|
demandInfo.maxPower = maxPower;
|
||||||
webTargets.setDemandControl(demandInfo);
|
|
||||||
savedDemandControlMaxPower = Optional.of(maxPower);
|
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();
|
DemandControl demandInfo = webTargets.getDemandControl();
|
||||||
try {
|
try {
|
||||||
demandInfo.setSchedule(schedule);
|
demandInfo.setSchedule(schedule);
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
logger.warn("Invalid schedule: {}. {}", schedule, e.getMessage());
|
logger.warn("Invalid schedule: {}. {}", schedule, e.getMessage());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
demandInfo.mode = DemandControlMode.SCHEDULED;
|
demandInfo.mode = DemandControlMode.SCHEDULED;
|
||||||
webTargets.setDemandControl(demandInfo);
|
|
||||||
savedDemandControlSchedule = Optional.of(demandInfo.getSchedule());
|
savedDemandControlSchedule = Optional.of(demandInfo.getSchedule());
|
||||||
|
return webTargets.setDemandControl(demandInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,8 +64,10 @@ public class DaikinAirbaseUnitHandler extends DaikinBaseHandler {
|
|||||||
throws DaikinCommunicationException {
|
throws DaikinCommunicationException {
|
||||||
if (channelUID.getId().startsWith(DaikinBindingConstants.CHANNEL_AIRBASE_AC_ZONE)) {
|
if (channelUID.getId().startsWith(DaikinBindingConstants.CHANNEL_AIRBASE_AC_ZONE)) {
|
||||||
int zoneNumber = Integer.parseInt(channelUID.getId().substring(4));
|
int zoneNumber = Integer.parseInt(channelUID.getId().substring(4));
|
||||||
if (command instanceof OnOffType) {
|
if (command instanceof OnOffType onOffCommand) {
|
||||||
changeZone(zoneNumber, command == OnOffType.ON);
|
if (changeZone(zoneNumber, onOffCommand == OnOffType.ON)) {
|
||||||
|
updateState(channelUID, onOffCommand);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,63 +112,63 @@ public class DaikinAirbaseUnitHandler extends DaikinBaseHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changePower(boolean power) throws DaikinCommunicationException {
|
protected boolean changePower(boolean power) throws DaikinCommunicationException {
|
||||||
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
||||||
info.power = power;
|
info.power = power;
|
||||||
webTargets.setAirbaseControlInfo(info);
|
return webTargets.setAirbaseControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeSetPoint(double newTemperature) throws DaikinCommunicationException {
|
protected boolean changeSetPoint(double newTemperature) throws DaikinCommunicationException {
|
||||||
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
||||||
info.temp = Optional.of(newTemperature);
|
info.temp = Optional.of(newTemperature);
|
||||||
webTargets.setAirbaseControlInfo(info);
|
return webTargets.setAirbaseControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeMode(String mode) throws DaikinCommunicationException {
|
protected boolean changeMode(String mode) throws DaikinCommunicationException {
|
||||||
AirbaseMode newMode;
|
AirbaseMode newMode;
|
||||||
try {
|
try {
|
||||||
newMode = AirbaseMode.valueOf(mode);
|
newMode = AirbaseMode.valueOf(mode);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
logger.warn("Invalid mode: {}. Valid values: {}", mode, AirbaseMode.values());
|
logger.warn("Invalid mode: {}. Valid values: {}", mode, AirbaseMode.values());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (airbaseModelInfo != null) {
|
if (airbaseModelInfo != null) {
|
||||||
if ((newMode == AirbaseMode.AUTO && !airbaseModelInfo.features.contains(AirbaseFeature.AUTO))
|
if ((newMode == AirbaseMode.AUTO && !airbaseModelInfo.features.contains(AirbaseFeature.AUTO))
|
||||||
|| (newMode == AirbaseMode.DRY && !airbaseModelInfo.features.contains(AirbaseFeature.DRY))) {
|
|| (newMode == AirbaseMode.DRY && !airbaseModelInfo.features.contains(AirbaseFeature.DRY))) {
|
||||||
logger.warn("{} mode is not supported by your controller", mode);
|
logger.warn("{} mode is not supported by your controller", mode);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
||||||
info.mode = newMode;
|
info.mode = newMode;
|
||||||
webTargets.setAirbaseControlInfo(info);
|
return webTargets.setAirbaseControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeFanSpeed(String speed) throws DaikinCommunicationException {
|
protected boolean changeFanSpeed(String speed) throws DaikinCommunicationException {
|
||||||
AirbaseFanSpeed newFanSpeed;
|
AirbaseFanSpeed newFanSpeed;
|
||||||
try {
|
try {
|
||||||
newFanSpeed = AirbaseFanSpeed.valueOf(speed);
|
newFanSpeed = AirbaseFanSpeed.valueOf(speed);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
logger.warn("Invalid fan speed: {}. Valid values: {}", speed, AirbaseFanSpeed.values());
|
logger.warn("Invalid fan speed: {}. Valid values: {}", speed, AirbaseFanSpeed.values());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (airbaseModelInfo != null) {
|
if (airbaseModelInfo != null) {
|
||||||
if (EnumSet.range(AirbaseFanSpeed.AUTO_LEVEL_1, AirbaseFanSpeed.AUTO_LEVEL_5).contains(newFanSpeed)
|
if (EnumSet.range(AirbaseFanSpeed.AUTO_LEVEL_1, AirbaseFanSpeed.AUTO_LEVEL_5).contains(newFanSpeed)
|
||||||
&& !airbaseModelInfo.features.contains(AirbaseFeature.FRATE_AUTO)) {
|
&& !airbaseModelInfo.features.contains(AirbaseFeature.FRATE_AUTO)) {
|
||||||
logger.warn("Fan AUTO_LEVEL_X is not supported by your controller");
|
logger.warn("Fan AUTO_LEVEL_X is not supported by your controller");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (newFanSpeed == AirbaseFanSpeed.AIRSIDE && !airbaseModelInfo.features.contains(AirbaseFeature.AIRSIDE)) {
|
if (newFanSpeed == AirbaseFanSpeed.AIRSIDE && !airbaseModelInfo.features.contains(AirbaseFeature.AIRSIDE)) {
|
||||||
logger.warn("Airside is not supported by your controller");
|
logger.warn("Airside is not supported by your controller");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
AirbaseControlInfo info = webTargets.getAirbaseControlInfo();
|
||||||
info.fanSpeed = newFanSpeed;
|
info.fanSpeed = newFanSpeed;
|
||||||
webTargets.setAirbaseControlInfo(info);
|
return webTargets.setAirbaseControlInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,7 +180,7 @@ public class DaikinAirbaseUnitHandler extends DaikinBaseHandler {
|
|||||||
* @param command true to turn on the zone, false to turn it off
|
* @param command true to turn on the zone, false to turn it off
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected void changeZone(int zone, boolean command) throws DaikinCommunicationException {
|
protected boolean changeZone(int zone, boolean command) throws DaikinCommunicationException {
|
||||||
AirbaseZoneInfo zoneInfo = webTargets.getAirbaseZoneInfo();
|
AirbaseZoneInfo zoneInfo = webTargets.getAirbaseZoneInfo();
|
||||||
long maxZones = zoneInfo.zone.length;
|
long maxZones = zoneInfo.zone.length;
|
||||||
|
|
||||||
@ -188,11 +190,11 @@ public class DaikinAirbaseUnitHandler extends DaikinBaseHandler {
|
|||||||
if (zone <= 0 || zone > maxZones) {
|
if (zone <= 0 || zone > maxZones) {
|
||||||
logger.warn("The given zone number ({}) is outside the number of zones supported by the controller ({})",
|
logger.warn("The given zone number ({}) is outside the number of zones supported by the controller ({})",
|
||||||
zone, maxZones);
|
zone, maxZones);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zoneInfo.zone[zone - 1] = command;
|
zoneInfo.zone[zone - 1] = command;
|
||||||
webTargets.setAirbaseZoneInfo(zoneInfo);
|
return webTargets.setAirbaseZoneInfo(zoneInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,13 +70,13 @@ public abstract class DaikinBaseHandler extends BaseThingHandler {
|
|||||||
// Abstract methods to be overridden by specific Daikin implementation class
|
// Abstract methods to be overridden by specific Daikin implementation class
|
||||||
protected abstract void pollStatus() throws DaikinCommunicationException;
|
protected abstract void pollStatus() throws DaikinCommunicationException;
|
||||||
|
|
||||||
protected abstract void changePower(boolean power) throws DaikinCommunicationException;
|
protected abstract boolean changePower(boolean power) throws DaikinCommunicationException;
|
||||||
|
|
||||||
protected abstract void changeSetPoint(double newTemperature) throws DaikinCommunicationException;
|
protected abstract boolean changeSetPoint(double newTemperature) throws DaikinCommunicationException;
|
||||||
|
|
||||||
protected abstract void changeMode(String mode) throws DaikinCommunicationException;
|
protected abstract boolean changeMode(String mode) throws DaikinCommunicationException;
|
||||||
|
|
||||||
protected abstract void changeFanSpeed(String fanSpeed) throws DaikinCommunicationException;
|
protected abstract boolean changeFanSpeed(String fanSpeed) throws DaikinCommunicationException;
|
||||||
|
|
||||||
// Power, Temp, Fan and Mode are handled in this base class. Override this to handle additional channels.
|
// Power, Temp, Fan and Mode are handled in this base class. Override this to handle additional channels.
|
||||||
protected abstract boolean handleCommandInternal(ChannelUID channelUID, Command command)
|
protected abstract boolean handleCommandInternal(ChannelUID channelUID, Command command)
|
||||||
@ -104,31 +104,54 @@ public abstract class DaikinBaseHandler extends BaseThingHandler {
|
|||||||
switch (channelUID.getId()) {
|
switch (channelUID.getId()) {
|
||||||
case DaikinBindingConstants.CHANNEL_AC_POWER:
|
case DaikinBindingConstants.CHANNEL_AC_POWER:
|
||||||
if (command instanceof OnOffType onOffCommand) {
|
if (command instanceof OnOffType onOffCommand) {
|
||||||
changePower(onOffCommand.equals(OnOffType.ON));
|
if (changePower(onOffCommand.equals(OnOffType.ON))) {
|
||||||
|
updateState(channelUID, onOffCommand);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_TEMP:
|
case DaikinBindingConstants.CHANNEL_AC_TEMP:
|
||||||
if (changeSetPoint(command)) {
|
double newTemperature;
|
||||||
return;
|
State newState = UnDefType.UNDEF;
|
||||||
|
if (command instanceof DecimalType decimalCommand) {
|
||||||
|
newTemperature = decimalCommand.doubleValue();
|
||||||
|
newState = decimalCommand;
|
||||||
|
} else if (command instanceof QuantityType) {
|
||||||
|
QuantityType<Temperature> quantityCommand = (QuantityType<Temperature>) command;
|
||||||
|
newTemperature = quantityCommand.toUnit(SIUnits.CELSIUS).doubleValue();
|
||||||
|
newState = quantityCommand;
|
||||||
|
} else {
|
||||||
|
break; // Exit switch statement but proceed to log about unsupported command type
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
// Only half degree increments are allowed, all others are silently rejected by the A/C units
|
||||||
|
newTemperature = Math.round(newTemperature * 2) / 2.0;
|
||||||
|
if (changeSetPoint(newTemperature)) {
|
||||||
|
updateState(channelUID, newState);
|
||||||
|
}
|
||||||
|
return; // return here and don't log about wrong type below
|
||||||
case DaikinBindingConstants.CHANNEL_AIRBASE_AC_FAN_SPEED:
|
case DaikinBindingConstants.CHANNEL_AIRBASE_AC_FAN_SPEED:
|
||||||
case DaikinBindingConstants.CHANNEL_AC_FAN_SPEED:
|
case DaikinBindingConstants.CHANNEL_AC_FAN_SPEED:
|
||||||
if (command instanceof StringType stringCommand) {
|
if (command instanceof StringType stringCommand) {
|
||||||
changeFanSpeed(stringCommand.toString());
|
if (changeFanSpeed(stringCommand.toString())) {
|
||||||
|
updateState(channelUID, stringCommand);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_HOMEKITMODE:
|
case DaikinBindingConstants.CHANNEL_AC_HOMEKITMODE:
|
||||||
if (command instanceof StringType) {
|
if (command instanceof StringType stringCommand) {
|
||||||
changeHomekitMode(command.toString());
|
if (changeHomekitMode(stringCommand.toString())) {
|
||||||
|
updateState(DaikinBindingConstants.CHANNEL_AC_HOMEKITMODE, stringCommand);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DaikinBindingConstants.CHANNEL_AC_MODE:
|
case DaikinBindingConstants.CHANNEL_AC_MODE:
|
||||||
if (command instanceof StringType stringCommand) {
|
if (command instanceof StringType stringCommand) {
|
||||||
changeMode(stringCommand.toString());
|
if (changeMode(stringCommand.toString())) {
|
||||||
|
updateState(channelUID, stringCommand);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -210,37 +233,37 @@ public abstract class DaikinBaseHandler extends BaseThingHandler {
|
|||||||
maybeTemperature.<State> map(t -> new QuantityType<>(t, SIUnits.CELSIUS)).orElse(UnDefType.UNDEF)));
|
maybeTemperature.<State> map(t -> new QuantityType<>(t, SIUnits.CELSIUS)).orElse(UnDefType.UNDEF)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean changeHomekitMode(String homekitmode) throws DaikinCommunicationException {
|
||||||
* @return true if the command was of an expected type, false otherwise
|
try {
|
||||||
*/
|
HomekitMode mode = HomekitMode.valueOf(homekitmode.toUpperCase());
|
||||||
private boolean changeSetPoint(Command command) throws DaikinCommunicationException {
|
boolean power = mode != HomekitMode.OFF;
|
||||||
double newTemperature;
|
if (!changePower(power)) {
|
||||||
if (command instanceof DecimalType decimalCommand) {
|
|
||||||
newTemperature = decimalCommand.doubleValue();
|
|
||||||
} else if (command instanceof QuantityType) {
|
|
||||||
newTemperature = ((QuantityType<Temperature>) command).toUnit(SIUnits.CELSIUS).doubleValue();
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only half degree increments are allowed, all others are silently rejected by the A/C units
|
boolean changeModeSuccess = false;
|
||||||
newTemperature = Math.round(newTemperature * 2) / 2.0;
|
updateState(DaikinBindingConstants.CHANNEL_AC_POWER, OnOffType.from(power));
|
||||||
changeSetPoint(newTemperature);
|
|
||||||
|
String newMode = switch (mode) {
|
||||||
|
case AUTO -> "AUTO";
|
||||||
|
case HEAT -> "HEAT";
|
||||||
|
case COOL -> "COLD";
|
||||||
|
case OFF -> null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (newMode == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeHomekitMode(String homekitmode) throws DaikinCommunicationException {
|
if (changeMode(newMode)) {
|
||||||
if (HomekitMode.OFF.getValue().equals(homekitmode)) {
|
updateState(DaikinBindingConstants.CHANNEL_AC_MODE, new StringType(newMode));
|
||||||
changePower(false);
|
return true;
|
||||||
} else {
|
}
|
||||||
changePower(true);
|
|
||||||
if (HomekitMode.AUTO.getValue().equals(homekitmode)) {
|
return false;
|
||||||
changeMode("AUTO");
|
} catch (IllegalArgumentException e) {
|
||||||
} else if (HomekitMode.HEAT.getValue().equals(homekitmode)) {
|
logger.warn("Invalid homekit mode: {}", homekitmode);
|
||||||
changeMode("HEAT");
|
return false;
|
||||||
} else if (HomekitMode.COOL.getValue().equals(homekitmode)) {
|
|
||||||
changeMode("COLD");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
<label>Power</label>
|
<label>Power</label>
|
||||||
<description>Power for the AC unit</description>
|
<description>Power for the AC unit</description>
|
||||||
<category>Switch</category>
|
<category>Switch</category>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-settemp">
|
<channel-type id="acunit-settemp">
|
||||||
@ -102,6 +103,7 @@
|
|||||||
<description>The set point temperature</description>
|
<description>The set point temperature</description>
|
||||||
<category>Temperature</category>
|
<category>Temperature</category>
|
||||||
<state pattern="%.1f %unit%" step="0.5"/>
|
<state pattern="%.1f %unit%" step="0.5"/>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-indoortemp">
|
<channel-type id="acunit-indoortemp">
|
||||||
@ -141,6 +143,7 @@
|
|||||||
<option value="FAN">fan</option>
|
<option value="FAN">fan</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-homekitmode">
|
<channel-type id="acunit-homekitmode">
|
||||||
@ -155,6 +158,7 @@
|
|||||||
<option value="off">Off</option>
|
<option value="off">Off</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-fan">
|
<channel-type id="acunit-fan">
|
||||||
@ -172,6 +176,7 @@
|
|||||||
<option value="LEVEL_5">level 5</option>
|
<option value="LEVEL_5">level 5</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-fandir">
|
<channel-type id="acunit-fandir">
|
||||||
@ -186,6 +191,7 @@
|
|||||||
<option value="VERTICAL_AND_HORIZONTAL">vertical and horizontal</option>
|
<option value="VERTICAL_AND_HORIZONTAL">vertical and horizontal</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-cmpfrequency" advanced="true">
|
<channel-type id="acunit-cmpfrequency" advanced="true">
|
||||||
@ -205,12 +211,14 @@
|
|||||||
<option value="POWERFUL">Powerful</option>
|
<option value="POWERFUL">Powerful</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-streamer" advanced="true">
|
<channel-type id="acunit-streamer" advanced="true">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Streamer</label>
|
<label>Streamer</label>
|
||||||
<description>Streamer Mode</description>
|
<description>Streamer Mode</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="acunit-energyheatingtoday" advanced="true">
|
<channel-type id="acunit-energyheatingtoday" advanced="true">
|
||||||
@ -442,6 +450,7 @@
|
|||||||
<option value="MANUAL">Manual</option>
|
<option value="MANUAL">Manual</option>
|
||||||
</options>
|
</options>
|
||||||
</state>
|
</state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
<channel-type id="acunit-demandcontrolmaxpower" advanced="true">
|
<channel-type id="acunit-demandcontrolmaxpower" advanced="true">
|
||||||
<item-type>Dimmer</item-type>
|
<item-type>Dimmer</item-type>
|
||||||
@ -449,65 +458,76 @@
|
|||||||
<description>The maximum power for demand control in percent. Allowed range is between 40% and 100% in increments of
|
<description>The maximum power for demand control in percent. Allowed range is between 40% and 100% in increments of
|
||||||
5%.</description>
|
5%.</description>
|
||||||
<state pattern="%d %%" min="40" max="100" step="5"></state>
|
<state pattern="%d %%" min="40" max="100" step="5"></state>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
<channel-type id="acunit-demandcontrolschedule" advanced="true">
|
<channel-type id="acunit-demandcontrolschedule" advanced="true">
|
||||||
<item-type>String</item-type>
|
<item-type>String</item-type>
|
||||||
<label>Demand Control Schedule</label>
|
<label>Demand Control Schedule</label>
|
||||||
<description>The demand control schedule in JSON format.</description>
|
<description>The demand control schedule in JSON format.</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-fan">
|
<channel-type id="airbase-acunit-fan">
|
||||||
<item-type>String</item-type>
|
<item-type>String</item-type>
|
||||||
<label>Fan</label>
|
<label>Fan</label>
|
||||||
<description>Current fan speed setting of the AC unit</description>
|
<description>Current fan speed setting of the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone1">
|
<channel-type id="airbase-acunit-zone1">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 1</label>
|
<label>Zone 1</label>
|
||||||
<description>Zone 1 for the AC unit</description>
|
<description>Zone 1 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone2">
|
<channel-type id="airbase-acunit-zone2">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 2</label>
|
<label>Zone 2</label>
|
||||||
<description>Zone 2 for the AC unit</description>
|
<description>Zone 2 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone3">
|
<channel-type id="airbase-acunit-zone3">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 3</label>
|
<label>Zone 3</label>
|
||||||
<description>Zone 3 for the AC unit</description>
|
<description>Zone 3 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone4">
|
<channel-type id="airbase-acunit-zone4">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 4</label>
|
<label>Zone 4</label>
|
||||||
<description>Zone 4 for the AC unit</description>
|
<description>Zone 4 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone5">
|
<channel-type id="airbase-acunit-zone5">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 5</label>
|
<label>Zone 5</label>
|
||||||
<description>Zone 5 for the AC unit</description>
|
<description>Zone 5 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone6">
|
<channel-type id="airbase-acunit-zone6">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 6</label>
|
<label>Zone 6</label>
|
||||||
<description>Zone 6 for the AC unit</description>
|
<description>Zone 6 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone7">
|
<channel-type id="airbase-acunit-zone7">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 7</label>
|
<label>Zone 7</label>
|
||||||
<description>Zone 7 for the AC unit</description>
|
<description>Zone 7 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="airbase-acunit-zone8">
|
<channel-type id="airbase-acunit-zone8">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Zone 8</label>
|
<label>Zone 8</label>
|
||||||
<description>Zone 8 for the AC unit</description>
|
<description>Zone 8 for the AC unit</description>
|
||||||
|
<autoUpdatePolicy>veto</autoUpdatePolicy>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
</thing:thing-descriptions>
|
</thing:thing-descriptions>
|
||||||
|
Loading…
Reference in New Issue
Block a user