diff --git a/bundles/org.openhab.binding.venstarthermostat/README.md b/bundles/org.openhab.binding.venstarthermostat/README.md index 1e82441aa1724..751460a23bd5c 100644 --- a/bundles/org.openhab.binding.venstarthermostat/README.md +++ b/bundles/org.openhab.binding.venstarthermostat/README.md @@ -41,20 +41,63 @@ After adding the Inbox item, enter the user name and password from the physical ### Channels -| 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) | | -| systemStateRaw | Number | System State Raw (Read Only) | 0 (Idle) 1 (Heating) 2 (Cooling) 3 (Lockout) 4 (Error) | -| heatingSetpoint | Number:Temperature | Heating Set Point | | -| coolingSetpoint | Number:Temperature | Cooling Set Point | | -| temperature | Number:Temperature | Current Temperature | | -| outdoorTemperature | Number:Temperature | Outdoor Temperature | | -| humidity | Number | Humidity | | - +| 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) | | +| systemStateRaw | Number | System State Raw (Read Only) | 0 (Idle) 1 (Heating) 2 (Cooling) 3 (Lockout) 4 (Error) | +| heatingSetpoint | Number:Temperature | Heating Set Point | | +| coolingSetpoint | Number:Temperature | Cooling Set Point | | +| temperature | Number:Temperature | Current Temperature | | +| outdoorTemperature | Number:Temperature | Outdoor Temperature | | +| humidity | Number | Humidity | | +| fanMode | String | Fan Mode | | +| fanModeRaw | Number | Fan Mode Raw (Read Only) | 0 (Auto) 1 (On) | +| fanState | String | Fan State (Read Only) | | +| fanStateRaw | Number | Fan State Raw (Read Only) | 0 (Off) 1 (On) | +| scheduleMode | String | Current Schedule Mode | | +| scheduleModeRaw | Number | Current Schedule mode Raw (Read Only) | 0(Disabled) 1(Enabled) | +| schedulePart | String | Current Schedule Part | | +| schedulePartRaw | Number | Schedule Part Raw (Read Only) | 0(Morning) 1(Day) 2(Evening) 3 (Night) 255 (Inactive) | + + +### Runtime data + +The Venstar thermostat provides data about how many minutes the system has been running in each of the different modes (heat1, heat2, cool1, cool2, aux1, aux2, free cool) every day for the last 7 days. +A time stamp is provided with each runtime data set which represents the end of each day. +The binding reads the runtime data and time stamps and provides them all as separate channels. + +| Channel | Type | Description | Notes | +|------------------------|----------------------|----------------------------------------------|------------------------------------------------------------| +| timestampDay0 | DateTime | Time Stamp of last runtime update | This is always the current time today | +| timestampDay1 | DateTime | Time Stamp of 00:00, end of yesterday | This represents the end of 1 day ago | +| timestampDay2 | DateTime | Time Stamp of 00:00 end of 2 days ago | This represents the end of 2 days ago | +| timestampDay3 | DateTime | Time Stamp of 00:00, end of 3 days ago | This represents the end of 3 days ago | +| timestampDay4 | DateTime | Time Stamp of 00:00, end of 4 days ago | This represents the end of 4 days ago | +| timestampDay5 | DateTime | Time Stamp of 00:00, end of 5 days ago | This represents the end of 5 days ago | +| timestampDay6 | DateTime | Time Stamp of 00:00, end of 6 days ago | This represents the end of 6 days ago | +| heat1RuntimeDay0 | Number:Dimensionless | Runtime in heat1 mode (minutes) today | This is the runtime between the Day 1 and Day 0 timestamps | +| heat1RuntimeDay1 | Number:Dimensionless | Runtime in heat1 mode (minutes) yesterday | This is the runtime between the Day 2 and Day 1 timestamps | +| heat1RuntimeDay2 | Number:Dimensionless | Runtime in heat1 mode (minutes) 2 days ago | This is the runtime between the Day 3 and Day 2 timestamps | +| heat1RuntimeDay3 | Number:Dimensionless | Runtime in heat1 mode (minutes) 3 days ago | This is the runtime between the Day 4 and Day 3 timestamps | +| heat1RuntimeDay4 | Number:Dimensionless | Runtime in heat1 mode (minutes) 4 days ago | This is the runtime between the Day 5 and Day 4 timestamps | +| heat1RuntimeDay5 | Number:Dimensionless | Runtime in heat1 mode (minutes) 5 days ago | This is the runtime between the Day 6 and Day 5 timestamps | +| heat1RuntimeDay6 | Number:Dimensionless | Runtime in heat1 mode (minutes) 6 days ago | This is the runtime in the 24hrs up to the Day 6 timestamp | +| | | | | +| heat2RuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in heat2 mode (minutes) | | +| | | | | +| cool1RuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in cool1 mode (minutes) | | +| | | | | +| cool2RuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in cool2 mode (minutes) | | +| | | | | +| aux1RuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in aux1 mode (minutes) | | +| | | | | +| aux2RuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in aux2 mode (minutes) | | +| | | | | +| freeCoolRuntimeDay0..6 | Number:Dimensionless | Similar Runtimes in free cool mode (minutes) | | ## Example @@ -71,10 +114,22 @@ Thing venstarthermostat:colorTouchThermostat:001122334455 "Venstar Thermostat (G Number:Temperature Guest_HVAC_Temperature "Temperature [%d °F]" {channel="venstarthermostat:colorTouchThermostat:001122334455:temperature"} Number:Temperature Guest_HVAC_HeatSetpoint "Heat Setpoint [%d °F]" {channel="venstarthermostat:colorTouchThermostat:001122334455:heatingSetpoint"} Number:Temperature Guest_HVAC_CoolSetpoint "Cool Setpoint [%d °F]" {channel="venstarthermostat:colorTouchThermostat:001122334455:coolingSetpoint"} -Number Guest_HVAC_Mode "Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:systemMode"} +String Guest_HVAC_Mode "System 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"} +String Guest_HVAC_State "State [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:systemState"} +String Guest_Away_Mode "Away Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:awayMode"} +String Guest_Fan_Mode "Fan Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:fanMode"} +String Guest_Fan_State "Fan State [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:fanState"} +String Guest_Schedule_Mode "Schedule Mode [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:scheduleMode"} +String Guest_Schedule_Part "Schedule Part [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:schedulePart"} +DateTime Guest_timestampDay0 "Date/Time Last Update [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:timestampDay0"} +Number Guest_heat1RuntimeDay0 "Heat1 Day0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:heat1RuntimeDay0"} +Number Guest_heat2RuntimeDay0 "Heat2 Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:heat2RuntimeDay0"} +Number Guest_cool1RuntimeDay0 "Cool1 Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:cool1RuntimeDay0"} +Number Guest_cool2RuntimeDay0 "Cool2 Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:cool2RuntimeDay0"} +Number Guest_aux1RuntimeDay0 "Aux1 Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:aux1RuntimeDay0"} +Number Guest_aux2RuntimeDay0 "Aux2 Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:aux2RuntimeDay0"} +Number Guest_freeCoolRuntimeDay0 "Free Cool Day 0 Run Time [%s]" {channel="venstarthermostat:colorTouchThermostat:001122334455:freeCoolRuntimeDay0"} ``` ### thermostat.sitemap @@ -88,6 +143,19 @@ sitemap demo label="Venstar Color Thermostat Demo" 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 + Switch item=Guest_Fan_Mode mappings=[auto=Auto, on=On] + Text item=Guest_Fan_State + Switch item=Guest_Schedule_Mode mappings=[enabled=Enabled,disabled=Disabled] + Text item=Guest_Schedule_Part + Text item=Guest_timestampDay0 + Text item=Guest_heat1RuntimeDay0 + Text item=Guest_heat2RuntimeDay0 + Text item=Guest_cool1RuntimeDay0 + Text item=Guest_cool2RuntimeDay0 + Text item=Guest_aux1RuntimeDay0 + Text item=Guest_aux2RuntimeDay0 + Text item=Guest_freeCoolRuntimeDay0 + } } ``` diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/VenstarThermostatBindingConstants.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/VenstarThermostatBindingConstants.java index 87378b210b990..035050be3cacb 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/VenstarThermostatBindingConstants.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/VenstarThermostatBindingConstants.java @@ -24,6 +24,7 @@ * * @author William Welliver - Initial contribution * @author Matthew Davies - added awayMode and awayModeRaw to include thermostat away mode in binding + * @author Matthew Davies - added more binding functionality to get close to the API functionality */ @NonNullByDefault public class VenstarThermostatBindingConstants { @@ -47,6 +48,23 @@ public class VenstarThermostatBindingConstants { public static final String CHANNEL_SYSTEM_MODE_RAW = "systemModeRaw"; public static final String CHANNEL_AWAY_MODE = "awayMode"; public static final String CHANNEL_AWAY_MODE_RAW = "awayModeRaw"; + public static final String CHANNEL_FAN_MODE = "fanMode"; + public static final String CHANNEL_FAN_MODE_RAW = "fanModeRaw"; + public static final String CHANNEL_FAN_STATE = "fanState"; + public static final String CHANNEL_FAN_STATE_RAW = "fanStateRaw"; + public static final String CHANNEL_SCHEDULE_MODE = "scheduleMode"; + public static final String CHANNEL_SCHEDULE_MODE_RAW = "scheduleModeRaw"; + public static final String CHANNEL_SCHEDULE_PART = "schedulePart"; + public static final String CHANNEL_SCHEDULE_PART_RAW = "schedulePartRaw"; + public static final String CHANNEL_TIMESTAMP_RUNTIME_DAY = "timestampDay"; + public static final String CHANNEL_HEAT1_RUNTIME_DAY = "heat1RuntimeDay"; + public static final String CHANNEL_HEAT2_RUNTIME_DAY = "heat2RuntimeDay"; + public static final String CHANNEL_COOL1_RUNTIME_DAY = "cool1RuntimeDay"; + public static final String CHANNEL_COOL2_RUNTIME_DAY = "cool2RuntimeDay"; + public static final String CHANNEL_AUX1_RUNTIME_DAY = "aux1RuntimeDay"; + public static final String CHANNEL_AUX2_RUNTIME_DAY = "aux2RuntimeDay"; + public static final String CHANNEL_FC_RUNTIME_DAY = "freeCoolRuntimeDay"; + // add query/runtimes and query/alerts - these will need an additional class similar to Venstar.infodata - more work public static final String CONFIG_USERNAME = "username"; public static final String CONFIG_PASSWORD = "password"; diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayMode.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayMode.java index 589929bfc295c..bf2bf13140def 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayMode.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayMode.java @@ -44,7 +44,7 @@ public String friendlyName() { return friendlyName; } - public static VenstarAwayMode fromInt(int mode) { + public static VenstarAwayMode fromInt(int mode) throws IllegalArgumentException { for (VenstarAwayMode am : values()) { if (am.mode == mode) { return am; diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java index 8ae818805d457..912d95f7d1361 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarAwayModeSerializer.java @@ -30,6 +30,10 @@ public class VenstarAwayModeSerializer implements JsonDeserializer { + @Override + public VenstarFanMode deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) + throws JsonParseException { + int key = element.getAsInt(); + try { + return VenstarFanMode.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanState.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanState.java new file mode 100644 index 0000000000000..f63034d1bfd20 --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanState.java @@ -0,0 +1,59 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link VenstarFanState} represents the state of the fan returned + * from the REST API. + * + * @author Matthew Davies - Initial contribution + */ +@NonNullByDefault +public enum VenstarFanState { + OFF(0, "off", "Off"), + ON(1, "on", "On"); + + private int state; + private String name; + private String friendlyName; + + VenstarFanState(int state, String name, String friendlyName) { + this.state = state; + this.name = name; + this.friendlyName = friendlyName; + } + + public int state() { + return state; + } + + public String stateName() { + return name; + } + + public String friendlyName() { + return friendlyName; + } + + public static VenstarFanState fromInt(int state) throws IllegalArgumentException { + for (VenstarFanState fs : values()) { + if (fs.state == state) { + return fs; + } + } + + throw (new IllegalArgumentException("Invalid fan state " + state)); + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanStateSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanStateSerializer.java new file mode 100644 index 0000000000000..c59023a6087fd --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarFanStateSerializer.java @@ -0,0 +1,40 @@ +/** + * 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.dto; + +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 VenstarFanStateSerializer} parses system mode values + * from the REST API JSON. + * + * @author Matthew Davies - Initial contribution + */ +public class VenstarFanStateSerializer implements JsonDeserializer { + @Override + public VenstarFanState deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) + throws JsonParseException { + + int key = element.getAsInt(); + try { + return VenstarFanState.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarInfoData.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarInfoData.java index b5a4aa9540d03..f123cbd84d5c8 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarInfoData.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarInfoData.java @@ -19,26 +19,35 @@ * @author Matthew Davies - added VenstarAwayMode to include away mode in binding */ public class VenstarInfoData { - double cooltemp; - double heattemp; - - VenstarSystemState state; - VenstarSystemMode mode; - VenstarAwayMode away; - int tempunits; + private double cooltemp; + private double heattemp; + + private VenstarSystemState state; + private VenstarSystemMode mode; + private VenstarAwayMode away; + private VenstarFanMode fan; + private VenstarFanState fanstate; + private VenstarScheduleMode schedule; + private VenstarSchedulePart schedulepart; + private int tempunits; public VenstarInfoData() { super(); } public VenstarInfoData(double cooltemp, double heattemp, VenstarSystemState state, VenstarSystemMode mode, - VenstarAwayMode away) { + VenstarAwayMode away, VenstarFanMode fan, VenstarFanState fanstate, VenstarScheduleMode schedule, + VenstarSchedulePart schedulepart) { super(); this.cooltemp = cooltemp; this.heattemp = heattemp; this.state = state; this.mode = mode; this.away = away; + this.fan = fan; + this.fanstate = fanstate; + this.schedule = schedule; + this.schedulepart = schedulepart; } public double getCooltemp() { @@ -57,19 +66,19 @@ public void setHeattemp(double heattemp) { this.heattemp = heattemp; } - public VenstarSystemState getState() { + public VenstarSystemState getSystemState() { return state; } - public void setState(VenstarSystemState state) { + public void setSystemState(VenstarSystemState state) { this.state = state; } - public VenstarSystemMode getMode() { + public VenstarSystemMode getSystemMode() { return mode; } - public void setMode(VenstarSystemMode mode) { + public void setSystemMode(VenstarSystemMode mode) { this.mode = mode; } @@ -81,11 +90,43 @@ public void setTempunits(int tempunits) { this.tempunits = tempunits; } - public VenstarAwayMode getAway() { + public VenstarAwayMode getAwayMode() { return away; } public void setAwayMode(VenstarAwayMode away) { this.away = away; } + + public VenstarFanMode getFanMode() { + return fan; + } + + public void setFanMode(VenstarFanMode fan) { + this.fan = fan; + } + + public VenstarFanState getFanState() { + return fanstate; + } + + public void setFanState(VenstarFanState fanstate) { + this.fanstate = fanstate; + } + + public VenstarScheduleMode getScheduleMode() { + return schedule; + } + + public void setScheduleMode(VenstarScheduleMode schedule) { + this.schedule = schedule; + } + + public VenstarSchedulePart getSchedulePart() { + return schedulepart; + } + + public void setSchedulePart(VenstarSchedulePart schedulepart) { + this.schedulepart = schedulepart; + } } diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntime.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntime.java new file mode 100644 index 0000000000000..80ab2e48b6328 --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntime.java @@ -0,0 +1,96 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link VenstarRunTime} represents one Runtime from the RuntimeData returned from the REST API + * + * @author Matthew Davies - Initial contribution + */ +@NonNullByDefault +public class VenstarRuntime { + private long ts; + private int heat1; + private int heat2; + private int cool1; + private int cool2; + private int aux1; + private int aux2; + private int fc; + + public long getTimeStamp() { + return ts; + } + + public void setTimeStamp(long ts) { + this.ts = ts; + } + + public int getHeat1Runtime() { + return heat1; + } + + public void setHeat1Runtime(int heat1) { + this.heat1 = heat1; + } + + public int getHeat2Runtime() { + return heat2; + } + + public void setHeat2Runtime(int heat2) { + this.heat2 = heat2; + } + + public int getCool1Runtime() { + return cool1; + } + + public void setCool1Runtime(int cool1) { + this.cool1 = cool1; + } + + public int getCool2Runtime() { + return cool2; + } + + public void setCool2Runtime(int cool2) { + this.cool2 = cool2; + } + + public int getAux1Runtime() { + return aux1; + } + + public void setAux1Runtime(int aux1) { + this.aux1 = aux1; + } + + public int getAux2Runtime() { + return aux2; + } + + public void setAux2Runtime(int aux2) { + this.aux2 = aux2; + } + + public int getFreeCoolRuntime() { + return fc; + } + + public void setFreeCoolRuntime(int fc) { + this.fc = fc; + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntimeData.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntimeData.java new file mode 100644 index 0000000000000..c2b86ceabfcb7 --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarRuntimeData.java @@ -0,0 +1,45 @@ +/** + * 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.dto; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link VenstarRunTimeData} represents the list of runtimes returned from the REST API. + * + * @author Matthew Davies - Initial contribution + */ +@NonNullByDefault +public class VenstarRuntimeData { + private List runtimes; + + public VenstarRuntimeData() { + super(); + runtimes = List.of(); + } + + public VenstarRuntimeData(List runtimes) { + super(); + this.runtimes = runtimes; + } + + public List getRuntimes() { + return runtimes; + } + + public void setRuntimes(List runtimes) { + this.runtimes = runtimes; + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleMode.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleMode.java new file mode 100644 index 0000000000000..ef2126feeed3b --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleMode.java @@ -0,0 +1,59 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link VenstarScheduleMode} represents the value of the schedule mode returned + * from the REST API. + * + * @author Matthew Davies - Initial contribution + */ +@NonNullByDefault +public enum VenstarScheduleMode { + DISABLED(0, "disabled", "Disabled"), + ENABLED(1, "enabled", "Enabled"); + + private int mode; + private String name; + private String friendlyName; + + VenstarScheduleMode(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 VenstarScheduleMode fromInt(int mode) throws IllegalArgumentException { + for (VenstarScheduleMode sm : values()) { + if (sm.mode == mode) { + return sm; + } + } + + throw (new IllegalArgumentException("Invalid schedule mode " + mode)); + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleModeSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleModeSerializer.java new file mode 100644 index 0000000000000..3b5a08e06d763 --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarScheduleModeSerializer.java @@ -0,0 +1,39 @@ +/** + * 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.dto; + +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 VenstarScheduleModeSerializer} parses schedule mode values + * from the REST API JSON. + * + * @author Matthew Davies - Initial contribution + */ +public class VenstarScheduleModeSerializer implements JsonDeserializer { + @Override + public VenstarScheduleMode deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) + throws JsonParseException { + int key = element.getAsInt(); + try { + return VenstarScheduleMode.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePart.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePart.java new file mode 100644 index 0000000000000..379f6fa801e88 --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePart.java @@ -0,0 +1,62 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * The {@link VenstarSchedulePart} represents the schedule part (part of day) returned + * from the REST API. + * + * @author Matthew Davies - Initial contribution + */ +@NonNullByDefault +public enum VenstarSchedulePart { + MORNING(0, "morning", "Morning"), + DAY(1, "day", "Day"), + EVENING(2, "evening", "Evening"), + NIGHT(3, "night", "Night"), + INACTIVE(255, "inactive", "Inactive"); + + private int part; + private String name; + private String friendlyName; + + VenstarSchedulePart(int part, String name, String friendlyName) { + this.part = part; + this.name = name; + this.friendlyName = friendlyName; + } + + public int part() { + return part; + } + + public String partName() { + return name; + } + + public String friendlyName() { + return friendlyName; + } + + public static VenstarSchedulePart fromInt(int part) throws IllegalArgumentException { + for (VenstarSchedulePart sp : values()) { + if (sp.part == part) { + return sp; + } + } + + throw (new IllegalArgumentException("Invalid schedule part " + part)); + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePartSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePartSerializer.java new file mode 100644 index 0000000000000..5a7f67f90673f --- /dev/null +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSchedulePartSerializer.java @@ -0,0 +1,39 @@ +/** + * 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.dto; + +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 VenstarSchedulePartSerializer} parses Schedule Part values + * from the REST API JSON. + * + * @author Matthew Davies - Initial contribution + */ +public class VenstarSchedulePartSerializer implements JsonDeserializer { + @Override + public VenstarSchedulePart deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) + throws JsonParseException { + int key = element.getAsInt(); + try { + return VenstarSchedulePart.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } +} diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemMode.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemMode.java index 680354958e567..357c3a4083736 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemMode.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemMode.java @@ -12,12 +12,15 @@ */ package org.openhab.binding.venstarthermostat.internal.dto; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link VenstarSystemMode} represents the value of the system mode returned * from the REST API. * * @author William Welliver - Initial contribution */ +@NonNullByDefault public enum VenstarSystemMode { OFF(0, "off", "Off"), HEAT(1, "heat", "Heat"), @@ -46,7 +49,7 @@ public String friendlyName() { return friendlyName; } - public static VenstarSystemMode fromInt(int mode) { + public static VenstarSystemMode fromInt(int mode) throws IllegalArgumentException { for (VenstarSystemMode sm : values()) { if (sm.mode == mode) { return sm; diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemModeSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemModeSerializer.java index cbb3a104a19fb..acb13fb33f05b 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemModeSerializer.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemModeSerializer.java @@ -24,12 +24,17 @@ * from the REST API JSON. * * @author William Welliver - Initial contribution + * @author Matthew Davies - added IllegalArgumentException handling */ public class VenstarSystemModeSerializer implements JsonDeserializer { @Override public VenstarSystemMode deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) throws JsonParseException { int key = element.getAsInt(); - return VenstarSystemMode.fromInt(key); + try { + return VenstarSystemMode.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } } } diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemState.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemState.java index ec0e9e9403503..af4eceb58cbbf 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemState.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemState.java @@ -12,12 +12,15 @@ */ package org.openhab.binding.venstarthermostat.internal.dto; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link VenstarSystemState} represents the value of the system state * returneda from the REST API. * * @author William Welliver - Initial contribution */ +@NonNullByDefault public enum VenstarSystemState { IDLE(0, "idle", "Idle"), HEATING(1, "heating", "Heating"), @@ -47,7 +50,7 @@ public String friendlyName() { return friendlyName; } - public static VenstarSystemState fromInt(int state) { + public static VenstarSystemState fromInt(int state) throws IllegalArgumentException { for (VenstarSystemState ss : values()) { if (ss.state == state) { return ss; diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemStateSerializer.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemStateSerializer.java index f7e1798d69570..79098cc91f660 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemStateSerializer.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/dto/VenstarSystemStateSerializer.java @@ -24,12 +24,17 @@ * from the REST API JSON. * * @author William Welliver - Initial contribution + * @author Matthew Davies - added IllegalArgumentException handling */ public class VenstarSystemStateSerializer implements JsonDeserializer { @Override public VenstarSystemState deserialize(JsonElement element, Type arg1, JsonDeserializationContext arg2) throws JsonParseException { int key = element.getAsInt(); - return VenstarSystemState.fromInt(key); + try { + return VenstarSystemState.fromInt(key); + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } } } diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/handler/VenstarThermostatHandler.java b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/handler/VenstarThermostatHandler.java index 5041eaff9c062..03927e7337058 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/handler/VenstarThermostatHandler.java +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/java/org/openhab/binding/venstarthermostat/internal/handler/VenstarThermostatHandler.java @@ -20,6 +20,10 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -49,8 +53,18 @@ import org.openhab.binding.venstarthermostat.internal.VenstarThermostatConfiguration; import org.openhab.binding.venstarthermostat.internal.dto.VenstarAwayMode; import org.openhab.binding.venstarthermostat.internal.dto.VenstarAwayModeSerializer; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarFanMode; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarFanModeSerializer; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarFanState; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarFanStateSerializer; import org.openhab.binding.venstarthermostat.internal.dto.VenstarInfoData; import org.openhab.binding.venstarthermostat.internal.dto.VenstarResponse; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarRuntime; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarRuntimeData; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarScheduleMode; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarScheduleModeSerializer; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarSchedulePart; +import org.openhab.binding.venstarthermostat.internal.dto.VenstarSchedulePartSerializer; import org.openhab.binding.venstarthermostat.internal.dto.VenstarSensor; import org.openhab.binding.venstarthermostat.internal.dto.VenstarSensorData; import org.openhab.binding.venstarthermostat.internal.dto.VenstarSystemMode; @@ -58,7 +72,9 @@ import org.openhab.binding.venstarthermostat.internal.dto.VenstarSystemState; import org.openhab.binding.venstarthermostat.internal.dto.VenstarSystemStateSerializer; import org.openhab.core.config.core.status.ConfigStatusMessage; +import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; +import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.ImperialUnits; @@ -90,13 +106,12 @@ */ @NonNullByDefault public class VenstarThermostatHandler extends ConfigStatusThingHandler { - private static final int TIMEOUT_SECONDS = 30; private static final int UPDATE_AFTER_COMMAND_SECONDS = 2; - private Logger log = LoggerFactory.getLogger(VenstarThermostatHandler.class); private List sensorData = new ArrayList<>(); private VenstarInfoData infoData = new VenstarInfoData(); + private VenstarRuntimeData runtimeData = new VenstarRuntimeData(); private Map stateMap = Collections.synchronizedMap(new HashMap<>()); private @Nullable Future updatesTask; private @Nullable URL baseURL; @@ -112,7 +127,11 @@ public VenstarThermostatHandler(Thing thing) { httpClient = new HttpClient(new SslContextFactory.Client(true)); gson = new GsonBuilder().registerTypeAdapter(VenstarSystemState.class, new VenstarSystemStateSerializer()) .registerTypeAdapter(VenstarSystemMode.class, new VenstarSystemModeSerializer()) - .registerTypeAdapter(VenstarAwayMode.class, new VenstarAwayModeSerializer()).create(); + .registerTypeAdapter(VenstarAwayMode.class, new VenstarAwayModeSerializer()) + .registerTypeAdapter(VenstarFanMode.class, new VenstarFanModeSerializer()) + .registerTypeAdapter(VenstarFanState.class, new VenstarFanStateSerializer()) + .registerTypeAdapter(VenstarScheduleMode.class, new VenstarScheduleModeSerializer()) + .registerTypeAdapter(VenstarSchedulePart.class, new VenstarSchedulePartSerializer()).create(); log.trace("VenstarThermostatHandler for thing {}", getThing().getUID()); } @@ -168,25 +187,63 @@ public void handleCommand(ChannelUID channelUID, Command command) { setCoolingSetpoint(value); } else if (channelUID.getId().equals(CHANNEL_SYSTEM_MODE)) { VenstarSystemMode value; - if (command instanceof StringType) { - value = VenstarSystemMode.valueOf(((StringType) command).toString().toUpperCase()); - } else { - value = VenstarSystemMode.fromInt(((DecimalType) command).intValue()); + try { + if (command instanceof StringType) { + value = VenstarSystemMode.valueOf(((StringType) command).toString().toUpperCase()); + } else { + value = VenstarSystemMode.fromInt(((DecimalType) command).intValue()); + } + log.debug("Setting system mode to {}", value); + setSystemMode(value); + updateIfChanged(CHANNEL_SYSTEM_MODE_RAW, new StringType(value.toString())); + } catch (IllegalArgumentException e) { + log.warn("Invalid System Mode"); } - log.debug("Setting system mode to {}", value); - setSystemMode(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()); + try { + 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())); + } catch (IllegalArgumentException e) { + log.warn("Invalid Away Mode"); + } + + } else if (channelUID.getId().equals(CHANNEL_FAN_MODE)) { + VenstarFanMode value; + try { + if (command instanceof StringType) { + value = VenstarFanMode.valueOf(((StringType) command).toString().toUpperCase()); + } else { + value = VenstarFanMode.fromInt(((DecimalType) command).intValue()); + } + log.debug("Setting fan mode to {}", value); + setFanMode(value); + updateIfChanged(CHANNEL_FAN_MODE_RAW, new StringType(value.toString())); + } catch (IllegalArgumentException e) { + log.warn("Invalid Fan Mode"); + } + } else if (channelUID.getId().equals(CHANNEL_SCHEDULE_MODE)) { + VenstarScheduleMode value; + try { + if (command instanceof StringType) { + value = VenstarScheduleMode.valueOf(((StringType) command).toString().toUpperCase()); + } else { + value = VenstarScheduleMode.fromInt(((DecimalType) command).intValue()); + } + log.debug("Setting schedule mode to {}", value); + setScheduleMode(value); + updateIfChanged(CHANNEL_SCHEDULE_MODE_RAW, new StringType(value.toString())); + } catch (IllegalArgumentException e) { + log.warn("Invalid Schedule Mode"); } - log.debug("Setting away mode to {}", value); - setAwayMode(value); - updateIfChanged(CHANNEL_AWAY_MODE_RAW, new StringType(value.toString())); } + startUpdatesTask(UPDATE_AFTER_COMMAND_SECONDS); } } @@ -298,24 +355,40 @@ private State getOutdoorTemperature() { private void setCoolingSetpoint(double cool) { double heat = getHeatingSetpoint().doubleValue(); - VenstarSystemMode mode = getSystemMode(); - updateControls(heat, cool, mode); + VenstarSystemMode mode = infoData.getSystemMode(); + VenstarFanMode fanmode = infoData.getFanMode(); + updateControls(heat, cool, mode, fanmode); } private void setSystemMode(VenstarSystemMode mode) { double cool = getCoolingSetpoint().doubleValue(); double heat = getHeatingSetpoint().doubleValue(); - updateControls(heat, cool, mode); + VenstarFanMode fanmode = infoData.getFanMode(); + updateControls(heat, cool, mode, fanmode); } private void setHeatingSetpoint(double heat) { double cool = getCoolingSetpoint().doubleValue(); - VenstarSystemMode mode = getSystemMode(); - updateControls(heat, cool, mode); + VenstarSystemMode mode = infoData.getSystemMode(); + VenstarFanMode fanmode = infoData.getFanMode(); + updateControls(heat, cool, mode, fanmode); + } + + private void setFanMode(VenstarFanMode fanmode) { + double cool = getCoolingSetpoint().doubleValue(); + double heat = getHeatingSetpoint().doubleValue(); + VenstarSystemMode mode = infoData.getSystemMode(); + updateControls(heat, cool, mode, fanmode); } private void setAwayMode(VenstarAwayMode away) { - updateSettings(away); + VenstarScheduleMode schedule = infoData.getScheduleMode(); + updateSettings(away, schedule); + } + + private void setScheduleMode(VenstarScheduleMode schedule) { + VenstarAwayMode away = infoData.getAwayMode(); + updateSettings(away, schedule); } private QuantityType getCoolingSetpoint() { @@ -326,35 +399,37 @@ private QuantityType getHeatingSetpoint() { return new QuantityType(infoData.getHeattemp(), unitSystem); } - private VenstarSystemState getSystemState() { - return infoData.getState(); - } - - private VenstarSystemMode getSystemMode() { - return infoData.getMode(); + private ZonedDateTime getTimestampRuntime(VenstarRuntime runtime) { + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime now = LocalDateTime.now().atZone(zoneId); + int diff = now.getOffset().getTotalSeconds(); + ZonedDateTime z = ZonedDateTime.ofInstant(Instant.ofEpochSecond(runtime.getTimeStamp() - diff), zoneId); + return z; } - private VenstarAwayMode getAwayMode() { - return infoData.getAway(); - } - - private void updateSettings(VenstarAwayMode away) { + private void updateSettings(VenstarAwayMode away, VenstarScheduleMode schedule) { // 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 + // settings that can be included are tempunits, away mode, schedule mode, humidifier setpoint, dehumidifier + // setpoint + // (hum/dehum are the only ones missing) Map params = new HashMap<>(); params.put("away", String.valueOf(away.mode())); + params.put("schedule", String.valueOf(schedule.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); + infoData.setScheduleMode(schedule); // add other parameters here in the same way } } - private void updateControls(double heat, double cool, VenstarSystemMode mode) { + private void updateControls(double heat, double cool, VenstarSystemMode mode, VenstarFanMode fanmode) { // 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 + // controls that can be included are thermostat mode, fan mode, heat temp, cool temp (all done already) Map params = new HashMap<>(); if (heat > 0) { params.put("heattemp", String.valueOf(heat)); @@ -363,13 +438,15 @@ private void updateControls(double heat, double cool, VenstarSystemMode mode) { params.put("cooltemp", String.valueOf(cool)); } params.put("mode", String.valueOf(mode.mode())); + params.put("fan", String.valueOf(fanmode.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); + infoData.setSystemMode(mode); + infoData.setFanMode(fanmode); // add other parameters here in the same way } } @@ -415,6 +492,29 @@ private void updateData() { updateIfChanged(CHANNEL_EXTERNAL_TEMPERATURE, getOutdoorTemperature()); updateIfChanged(CHANNEL_HUMIDITY, getHumidity()); + response = getData("/query/runtimes"); + if (!isFutureValid(localUpdatesTask)) { + return; + } + + runtimeData = Objects.requireNonNull(gson.fromJson(response, VenstarRuntimeData.class)); + List runtimes = runtimeData.getRuntimes(); + Collections.reverse(runtimes);// reverse the list so that the most recent runtime data is first in the list + int nRuntimes = Math.min(7, runtimes.size());// check how many runtimes are available, might be less than + // seven if equipment + // was reset, and also might be more than 7, so limit to 7 + for (int i = 0; i < nRuntimes; i++) { + VenstarRuntime rt = runtimes.get(i); + updateIfChanged(CHANNEL_TIMESTAMP_RUNTIME_DAY + i, new DateTimeType(getTimestampRuntime(rt))); + updateIfChanged(CHANNEL_HEAT1_RUNTIME_DAY + i, new DecimalType(rt.getHeat1Runtime())); + updateIfChanged(CHANNEL_HEAT2_RUNTIME_DAY + i, new DecimalType(rt.getHeat2Runtime())); + updateIfChanged(CHANNEL_COOL1_RUNTIME_DAY + i, new DecimalType(rt.getCool1Runtime())); + updateIfChanged(CHANNEL_COOL2_RUNTIME_DAY + i, new DecimalType(rt.getCool2Runtime())); + updateIfChanged(CHANNEL_AUX1_RUNTIME_DAY + i, new DecimalType(rt.getAux1Runtime())); + updateIfChanged(CHANNEL_AUX2_RUNTIME_DAY + i, new DecimalType(rt.getAux2Runtime())); + updateIfChanged(CHANNEL_FC_RUNTIME_DAY + i, new DecimalType(rt.getFreeCoolRuntime())); + } + response = getData("/query/info"); if (!isFutureValid(localUpdatesTask)) { return; @@ -423,12 +523,20 @@ private void updateData() { updateUnits(infoData); updateIfChanged(CHANNEL_HEATING_SETPOINT, getHeatingSetpoint()); updateIfChanged(CHANNEL_COOLING_SETPOINT, getCoolingSetpoint()); - updateIfChanged(CHANNEL_SYSTEM_STATE, new StringType(getSystemState().stateName())); - 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())); + updateIfChanged(CHANNEL_SYSTEM_STATE, new StringType(infoData.getSystemState().stateName())); + updateIfChanged(CHANNEL_SYSTEM_MODE, new StringType(infoData.getSystemMode().modeName())); + updateIfChanged(CHANNEL_SYSTEM_STATE_RAW, new DecimalType(infoData.getSystemState().state())); + updateIfChanged(CHANNEL_SYSTEM_MODE_RAW, new DecimalType(infoData.getSystemMode().mode())); + updateIfChanged(CHANNEL_AWAY_MODE, new StringType(infoData.getAwayMode().modeName())); + updateIfChanged(CHANNEL_AWAY_MODE_RAW, new DecimalType(infoData.getAwayMode().mode())); + updateIfChanged(CHANNEL_FAN_MODE, new StringType(infoData.getFanMode().modeName())); + updateIfChanged(CHANNEL_FAN_MODE_RAW, new DecimalType(infoData.getFanMode().mode())); + updateIfChanged(CHANNEL_FAN_STATE, OnOffType.from(infoData.getFanState().stateName())); + updateIfChanged(CHANNEL_FAN_STATE_RAW, new DecimalType(infoData.getFanState().state())); + updateIfChanged(CHANNEL_SCHEDULE_MODE, new StringType(infoData.getScheduleMode().modeName())); + updateIfChanged(CHANNEL_SCHEDULE_MODE_RAW, new DecimalType(infoData.getScheduleMode().mode())); + updateIfChanged(CHANNEL_SCHEDULE_PART, new StringType(infoData.getSchedulePart().partName())); + updateIfChanged(CHANNEL_SCHEDULE_PART_RAW, new DecimalType(infoData.getSchedulePart().part())); goOnline(); } catch (VenstarCommunicationException | JsonSyntaxException e) { diff --git a/bundles/org.openhab.binding.venstarthermostat/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.venstarthermostat/src/main/resources/OH-INF/thing/thing-types.xml index a9c6d5061c672..b027573541532 100644 --- a/bundles/org.openhab.binding.venstarthermostat/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.venstarthermostat/src/main/resources/OH-INF/thing/thing-types.xml @@ -21,6 +21,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -89,6 +152,136 @@ + + String + + Current Fan Mode + + + + + + + + + + Number + + Current Fan Mode, as an integer number + + + + + Switch + + Current Fan State + + + + + Number + + Current Fan State, as an integer number + + + + + String + + Current Schedule Mode + + + + + + + + + + Number + + Current Schedule Mode, as an integer number + + + + + String + + Current Schedule Part + + + + + + + + + + + + + Number + + Current Schedule Part, as an integer number + + + + + DateTime + + Time stamp of Runtime Update (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in heat1 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in heat2 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in cool1 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in cool2 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in aux1 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in aux2 mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + + + Number + + Run time in Free Cool mode in minutes (Day 0 = TODAY, Day 6 = 6 days ago) + + + String