[venstarthermostat] Venstar thermostat away mode enhancement (#10736)
* [VENSTAR THERMOSTAT BINDING] ADD AWAY MODE Signed-off-by: Matthew Davies matthew.davies@skynet.be Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com> * [VENSTAR THERMOSTAT] FIXED COMMAND AWAY MODE Signed-off-by: Matthew Davies matthew.davies@skynet.be Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com> * VENSTAR THERMOSTAT AWAY MODE AFTER INITIAL COMMIT FEEDBACK This code includes the Away mode of the Venstar thermostat. It is updated following initial feedback and suggestions on my first version from @digitaldan. Signed-off-by: Matthew Davies <matthew.davies@skynet.be> Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com> * VENSTAR THERMOSTAT BINDING - INCLUDE AWAY MODE Removed the updateThermostat function, now have updateSettings and updateControls corresponding to local API URLs. Signed-off-by: Matthew Davies <matthew.davies@skynet.be> Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com> * VENSTAR THERMOSTAT AWAY MODE - Modification updated as per feedback 1 June 2021 Signed-off-by: Matthew Davies <matthew.davies@skynet.be> Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com> * VENSTAR THERMOSTAT AWAY MODE INCLUSION - UPDATED README Signed-off-by: Matthew Davies <matthew.davies@skynet.be> Signed-off-by: raveydavies <84205523+raveydavies@users.noreply.github.com>
This commit is contained in:
parent
33b7fd6e98
commit
503abab181
|
@ -43,6 +43,8 @@ After adding the Inbox item, enter the user name and password from the physical
|
|||
|
||||
| Channel | Type | Description | Notes |
|
||||
|--------------------|--------------------|------------------------------|--------------------------------------------------------|
|
||||
| awayMode | String | Home or Away Mode | |
|
||||
| awayModeRaw | Number | Away Mode Raw (Read Only) | 0 (Home) 1 (Away) |
|
||||
| systemMode | String | System Mode | |
|
||||
| systemModeRaw | Number | System Mode Raw (Read Only) | 0 (Off) 1 (Heat) 2 (Cool) 3 (Auto) |
|
||||
| systemState | String | System State (Read Only) | |
|
||||
|
@ -72,6 +74,7 @@ Number:Temperature Guest_HVAC_CoolSetpoint "Cool Setpoint [%d °F]" {channel="v
|
|||
Number Guest_HVAC_Mode "Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:systemMode"}
|
||||
Number Guest_HVAC_Humidity "Humidity [%d %%]" {channel="venstarthermostat:colorTouchThermostat:001122334455:humidity"}
|
||||
Number Guest_HVAC_State "State [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:systemState"}
|
||||
Number Guest_Away_Mode "Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:awayMode"}
|
||||
```
|
||||
|
||||
### thermostat.sitemap
|
||||
|
@ -83,6 +86,7 @@ sitemap demo label="Venstar Color Thermostat Demo"
|
|||
Setpoint item=Guest_HVAC_HeatSetpoint minValue=50 maxValue=99
|
||||
Setpoint item=Guest_HVAC_CoolSetpoint minValue=50 maxValue=99
|
||||
Switch item=Guest_HVAC_Mode mappings=[off=Off,heat=Heat,cool=Cool,auto=Auto]
|
||||
Switch item=Guest_Away_Mode mappings=[home=Home,away=Away]
|
||||
Text item=Guest_HVAC_State
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||
* used across the whole binding.
|
||||
*
|
||||
* @author William Welliver - Initial contribution
|
||||
* @author Matthew Davies - added awayMode and awayModeRaw to include thermostat away mode in binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class VenstarThermostatBindingConstants {
|
||||
|
@ -44,6 +45,8 @@ public class VenstarThermostatBindingConstants {
|
|||
public final static String CHANNEL_SYSTEM_MODE = "systemMode";
|
||||
public final static String CHANNEL_SYSTEM_STATE_RAW = "systemStateRaw";
|
||||
public final static String CHANNEL_SYSTEM_MODE_RAW = "systemModeRaw";
|
||||
public final static String CHANNEL_AWAY_MODE = "awayMode";
|
||||
public final static String CHANNEL_AWAY_MODE_RAW = "awayModeRaw";
|
||||
|
||||
public final static String CONFIG_USERNAME = "username";
|
||||
public final static String CONFIG_PASSWORD = "password";
|
||||
|
|
|
@ -47,6 +47,8 @@ import org.eclipse.jetty.client.util.DigestAuthentication;
|
|||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.openhab.binding.venstarthermostat.internal.VenstarThermostatConfiguration;
|
||||
import org.openhab.binding.venstarthermostat.internal.model.VenstarAwayMode;
|
||||
import org.openhab.binding.venstarthermostat.internal.model.VenstarAwayModeSerializer;
|
||||
import org.openhab.binding.venstarthermostat.internal.model.VenstarInfoData;
|
||||
import org.openhab.binding.venstarthermostat.internal.model.VenstarResponse;
|
||||
import org.openhab.binding.venstarthermostat.internal.model.VenstarSensor;
|
||||
|
@ -84,6 +86,7 @@ import com.google.gson.JsonSyntaxException;
|
|||
*
|
||||
* @author William Welliver - Initial contribution
|
||||
* @author Dan Cunningham - Migration to Jetty, annotations and various improvements
|
||||
* @author Matthew Davies - added code to include away mode in binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
||||
|
@ -108,7 +111,8 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
super(thing);
|
||||
httpClient = new HttpClient(new SslContextFactory.Client(true));
|
||||
gson = new GsonBuilder().registerTypeAdapter(VenstarSystemState.class, new VenstarSystemStateSerializer())
|
||||
.registerTypeAdapter(VenstarSystemMode.class, new VenstarSystemModeSerializer()).create();
|
||||
.registerTypeAdapter(VenstarSystemMode.class, new VenstarSystemModeSerializer())
|
||||
.registerTypeAdapter(VenstarAwayMode.class, new VenstarAwayModeSerializer()).create();
|
||||
|
||||
log.trace("VenstarThermostatHandler for thing {}", getThing().getUID());
|
||||
}
|
||||
|
@ -173,7 +177,17 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
}
|
||||
log.debug("Setting system mode to {}", value);
|
||||
setSystemMode(value);
|
||||
updateIfChanged(CHANNEL_SYSTEM_MODE_RAW, new StringType("" + value));
|
||||
updateIfChanged(CHANNEL_SYSTEM_MODE_RAW, new StringType(value.toString()));
|
||||
} else if (channelUID.getId().equals(CHANNEL_AWAY_MODE)) {
|
||||
VenstarAwayMode value;
|
||||
if (command instanceof StringType) {
|
||||
value = VenstarAwayMode.valueOf(((StringType) command).toString().toUpperCase());
|
||||
} else {
|
||||
value = VenstarAwayMode.fromInt(((DecimalType) command).intValue());
|
||||
}
|
||||
log.debug("Setting away mode to {}", value);
|
||||
setAwayMode(value);
|
||||
updateIfChanged(CHANNEL_AWAY_MODE_RAW, new StringType(value.toString()));
|
||||
}
|
||||
startUpdatesTask(UPDATE_AFTER_COMMAND_SECONDS);
|
||||
}
|
||||
|
@ -287,19 +301,23 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
private void setCoolingSetpoint(int cool) {
|
||||
int heat = getHeatingSetpoint().intValue();
|
||||
VenstarSystemMode mode = getSystemMode();
|
||||
updateThermostat(heat, cool, mode);
|
||||
updateControls(heat, cool, mode);
|
||||
}
|
||||
|
||||
private void setSystemMode(VenstarSystemMode mode) {
|
||||
int cool = getCoolingSetpoint().intValue();
|
||||
int heat = getHeatingSetpoint().intValue();
|
||||
updateThermostat(heat, cool, mode);
|
||||
updateControls(heat, cool, mode);
|
||||
}
|
||||
|
||||
private void setHeatingSetpoint(int heat) {
|
||||
int cool = getCoolingSetpoint().intValue();
|
||||
VenstarSystemMode mode = getSystemMode();
|
||||
updateThermostat(heat, cool, mode);
|
||||
updateControls(heat, cool, mode);
|
||||
}
|
||||
|
||||
private void setAwayMode(VenstarAwayMode away) {
|
||||
updateSettings(away);
|
||||
}
|
||||
|
||||
private QuantityType<Temperature> getCoolingSetpoint() {
|
||||
|
@ -318,26 +336,63 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
return infoData.getMode();
|
||||
}
|
||||
|
||||
private void updateThermostat(int heat, int cool, VenstarSystemMode mode) {
|
||||
private VenstarAwayMode getAwayMode() {
|
||||
return infoData.getAway();
|
||||
}
|
||||
|
||||
private void updateSettings(VenstarAwayMode away) {
|
||||
// this function corresponds to the thermostat local API POST /settings instruction
|
||||
// the function can be expanded with other parameters which are changed via POST /settings
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("away", String.valueOf(away.mode()));
|
||||
VenstarResponse res = updateThermostat("/settings", params);
|
||||
if (res != null) {
|
||||
log.debug("Updated thermostat");
|
||||
// update our local copy until the next refresh occurs
|
||||
infoData.setAwayMode(away);
|
||||
// add other parameters here in the same way
|
||||
}
|
||||
}
|
||||
|
||||
private void updateControls(int heat, int cool, VenstarSystemMode mode) {
|
||||
// this function corresponds to the thermostat local API POST /control instruction
|
||||
// the function can be expanded with other parameters which are changed via POST /control
|
||||
Map<String, String> params = new HashMap<>();
|
||||
log.debug("Updating thermostat {} heat:{} cool {} mode: {}", getThing().getLabel(), heat, cool, mode);
|
||||
if (heat > 0) {
|
||||
params.put("heattemp", String.valueOf(heat));
|
||||
}
|
||||
if (cool > 0) {
|
||||
params.put("cooltemp", String.valueOf(cool));
|
||||
}
|
||||
params.put("mode", "" + mode.mode());
|
||||
params.put("mode", String.valueOf(mode.mode()));
|
||||
VenstarResponse res = updateThermostat("/control", params);
|
||||
if (res != null) {
|
||||
log.debug("Updated thermostat");
|
||||
// update our local copy until the next refresh occurs
|
||||
infoData.setCooltemp(cool);
|
||||
infoData.setHeattemp(heat);
|
||||
infoData.setMode(mode);
|
||||
// add other parameters here in the same way
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to send data to the thermostat and update the Thing state if there is an error
|
||||
*
|
||||
* @param path
|
||||
* @param params
|
||||
* @return VenstarResponse object or null if there was an error
|
||||
*/
|
||||
private @Nullable VenstarResponse updateThermostat(String path, Map<String, String> params) {
|
||||
try {
|
||||
String result = postData("/control", params);
|
||||
String result = postData(path, params);
|
||||
VenstarResponse res = gson.fromJson(result, VenstarResponse.class);
|
||||
if (res.isSuccess()) {
|
||||
log.debug("Updated thermostat");
|
||||
// update our local copy until the next refresh occurs
|
||||
infoData = new VenstarInfoData(cool, heat, infoData.getState(), mode);
|
||||
if (res != null && res.isSuccess()) {
|
||||
return res;
|
||||
} else {
|
||||
log.debug("Failed to update thermostat: {}", res.getReason());
|
||||
goOffline(ThingStatusDetail.COMMUNICATION_ERROR, "Thermostat update failed: " + res.getReason());
|
||||
String reason = res == null ? "invalid response" : res.getReason();
|
||||
log.debug("Failed to update thermostat: {}", reason);
|
||||
goOffline(ThingStatusDetail.COMMUNICATION_ERROR, reason);
|
||||
}
|
||||
} catch (VenstarCommunicationException | JsonSyntaxException e) {
|
||||
log.debug("Unable to fetch info data", e);
|
||||
|
@ -346,6 +401,7 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
} catch (VenstarAuthenticationException e) {
|
||||
goOffline(ThingStatusDetail.CONFIGURATION_ERROR, "Authorization Failed");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateData() {
|
||||
|
@ -373,6 +429,8 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
updateIfChanged(CHANNEL_SYSTEM_MODE, new StringType(getSystemMode().modeName()));
|
||||
updateIfChanged(CHANNEL_SYSTEM_STATE_RAW, new DecimalType(getSystemState().state()));
|
||||
updateIfChanged(CHANNEL_SYSTEM_MODE_RAW, new DecimalType(getSystemMode().mode()));
|
||||
updateIfChanged(CHANNEL_AWAY_MODE, new StringType(getAwayMode().modeName()));
|
||||
updateIfChanged(CHANNEL_AWAY_MODE_RAW, new DecimalType(getAwayMode().mode()));
|
||||
|
||||
goOnline();
|
||||
} catch (VenstarCommunicationException | JsonSyntaxException e) {
|
||||
|
@ -438,7 +496,7 @@ public class VenstarThermostatHandler extends ConfigStatusThingHandler {
|
|||
|
||||
if (response.getStatus() != 200) {
|
||||
throw new VenstarCommunicationException(
|
||||
"Error communitcating with thermostat. Error Code: " + response.getStatus());
|
||||
"Error communicating with thermostat. Error Code: " + response.getStatus());
|
||||
}
|
||||
String content = response.getContentAsString();
|
||||
log.trace("sendRequest: response {}", content);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.venstarthermostat.internal.model;
|
||||
|
||||
/**
|
||||
* The {@link VenstarSystemMode} represents the value of the system mode returned
|
||||
* from the REST API.
|
||||
*
|
||||
* @author Matthew Davies - created new class to add away mode to binding
|
||||
*/
|
||||
public enum VenstarAwayMode {
|
||||
HOME(0, "home", "Home"),
|
||||
AWAY(1, "away", "Away");
|
||||
|
||||
private int mode;
|
||||
private String name;
|
||||
private String friendlyName;
|
||||
|
||||
VenstarAwayMode(int mode, String name, String friendlyName) {
|
||||
this.mode = mode;
|
||||
this.name = name;
|
||||
this.friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
public int mode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public String modeName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String friendlyName() {
|
||||
return friendlyName;
|
||||
}
|
||||
|
||||
public static VenstarAwayMode fromInt(int mode) {
|
||||
for (VenstarAwayMode am : values()) {
|
||||
if (am.mode == mode) {
|
||||
return am;
|
||||
}
|
||||
}
|
||||
|
||||
throw (new IllegalArgumentException("Invalid away mode " + mode));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.venstarthermostat.internal.model;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
/**
|
||||
* The {@link VenstarSystemModeSerializer} parses system mode values
|
||||
* from the REST API JSON.
|
||||
*
|
||||
* @author Matthew Davies - created new class to include away mode in binding
|
||||
*/
|
||||
public class VenstarAwayModeSerializer implements JsonDeserializer<VenstarAwayMode> {
|
||||
@Override
|
||||
public VenstarAwayMode deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2)
|
||||
throws JsonParseException {
|
||||
int key = element.getAsInt();
|
||||
return VenstarAwayMode.fromInt(key);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ package org.openhab.binding.venstarthermostat.internal.model;
|
|||
* The {@link VenstarInfoData} represents a thermostat state from the REST API.
|
||||
*
|
||||
* @author William Welliver - Initial contribution
|
||||
* @author Matthew Davies - added VenstarAwayMode to include away mode in binding
|
||||
*/
|
||||
public class VenstarInfoData {
|
||||
double cooltemp;
|
||||
|
@ -23,18 +24,21 @@ public class VenstarInfoData {
|
|||
|
||||
VenstarSystemState state;
|
||||
VenstarSystemMode mode;
|
||||
VenstarAwayMode away;
|
||||
int tempunits;
|
||||
|
||||
public VenstarInfoData() {
|
||||
super();
|
||||
}
|
||||
|
||||
public VenstarInfoData(double cooltemp, double heattemp, VenstarSystemState state, VenstarSystemMode mode) {
|
||||
public VenstarInfoData(double cooltemp, double heattemp, VenstarSystemState state, VenstarSystemMode mode,
|
||||
VenstarAwayMode away) {
|
||||
super();
|
||||
this.cooltemp = cooltemp;
|
||||
this.heattemp = heattemp;
|
||||
this.state = state;
|
||||
this.mode = mode;
|
||||
this.away = away;
|
||||
}
|
||||
|
||||
public double getCooltemp() {
|
||||
|
@ -76,4 +80,12 @@ public class VenstarInfoData {
|
|||
public void setTempunits(int tempunits) {
|
||||
this.tempunits = tempunits;
|
||||
}
|
||||
|
||||
public VenstarAwayMode getAway() {
|
||||
return away;
|
||||
}
|
||||
|
||||
public void setAwayMode(VenstarAwayMode away) {
|
||||
this.away = away;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
<channel id="coolingSetpoint" typeId="coolingSetpoint"/>
|
||||
<channel id="systemState" typeId="systemState"/>
|
||||
<channel id="systemStateRaw" typeId="systemStateRaw"/>
|
||||
<channel id="awayMode" typeId="awayMode"/>
|
||||
<channel id="awayModeRaw" typeId="awayModeRaw"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
|
@ -68,6 +70,25 @@
|
|||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="awayMode">
|
||||
<item-type>String</item-type>
|
||||
<label>Away Mode</label>
|
||||
<description>Current Away Mode</description>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="home">Home</option>
|
||||
<option value="away">Away</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="awayModeRaw" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Away Mode (Raw)</label>
|
||||
<description>Current Away Mode, as an integer number</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="systemState">
|
||||
<item-type>String</item-type>
|
||||
<label>System State</label>
|
||||
|
|
Loading…
Reference in New Issue