[radiothermostat] Add Remote Temperature channel (#10194)
* Add Remote Temperature channel Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * Fix spelling error Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * Fix spelling error2 Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * review changes Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * review changes Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * review changes Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com> * minor README update Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
parent
3561388061
commit
035556bc55
@ -1,5 +1,7 @@
|
||||
# RadioThermostat Binding
|
||||
|
||||

|
||||
|
||||
This binding connects RadioThermostat/3M Filtrete models CT30, CT50/3M50, CT80, etc. with built-in Wi-Fi module to openHAB.
|
||||
|
||||
The binding retrieves and periodically updates all basic system information from the thermostat.
|
||||
@ -45,26 +47,27 @@ The thing has a few configuration parameters:
|
||||
|
||||
The thermostat information that is retrieved is available as these channels:
|
||||
|
||||
| Channel ID | Item Type | Description |
|
||||
|------------------------|----------------------|---------------------------------------------------------------------------|
|
||||
| temperature | Number:Temperature | The current temperature reading of the thermostat |
|
||||
| humidity | Number:Dimensionless | The current humidity reading of the thermostat (CT80 only) |
|
||||
| mode | Number | The current operating mode of the HVAC system |
|
||||
| fan_mode | Number | The current operating mode of the fan |
|
||||
| program_mode | Number | The program schedule that the thermostat is running (CT80 Rev B only) |
|
||||
| set_point | Number:Temperature | The current temperature set point of the thermostat |
|
||||
| status | Number | Indicates the current running status of the HVAC system |
|
||||
| fan_status | Number | Indicates the current fan status of the HVAC system |
|
||||
| override | Number | Indicates if the normal program set-point has been manually overridden |
|
||||
| hold | Switch | Indicates if the current set point temperature is to be held indefinitely |
|
||||
| day | Number | The current day of the week reported by the thermostat (0 = Monday) |
|
||||
| hour | Number | The current hour of the day reported by the thermostat (24 hr) |
|
||||
| minute | Number | The current minute past the hour reported by the thermostat |
|
||||
| dt_stamp | String | The current day of the week and time reported by the thermostat (E HH:mm) |
|
||||
| today_heat_runtime | Number:Time | The total number of minutes of heating run-time today |
|
||||
| today_cool_runtime | Number:Time | The total number of minutes of cooling run-time today |
|
||||
| yesterday_heat_runtime | Number:Time | The total number of minutes of heating run-time yesterday |
|
||||
| yesterday_cool_runtime | Number:Time | The total number of minutes of cooling run-time yesterday |
|
||||
| Channel ID | Item Type | Description |
|
||||
|------------------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| temperature | Number:Temperature | The current temperature reading of the thermostat |
|
||||
| humidity | Number:Dimensionless | The current humidity reading of the thermostat (CT80 only) |
|
||||
| mode | Number | The current operating mode of the HVAC system |
|
||||
| fan_mode | Number | The current operating mode of the fan |
|
||||
| program_mode | Number | The program schedule that the thermostat is running (CT80 Rev B only) |
|
||||
| set_point | Number:Temperature | The current temperature set point of the thermostat |
|
||||
| status | Number | Indicates the current running status of the HVAC system |
|
||||
| fan_status | Number | Indicates the current fan status of the HVAC system |
|
||||
| override | Number | Indicates if the normal program set-point has been manually overridden |
|
||||
| hold | Switch | Indicates if the current set point temperature is to be held indefinitely |
|
||||
| remote_temp | Number:Temperature | Override the internal temperature as read by the thermostat's temperature sensor; Set to -1 to return to internal temperature mode |
|
||||
| day | Number | The current day of the week reported by the thermostat (0 = Monday) |
|
||||
| hour | Number | The current hour of the day reported by the thermostat (24 hr) |
|
||||
| minute | Number | The current minute past the hour reported by the thermostat |
|
||||
| dt_stamp | String | The current day of the week and time reported by the thermostat (E HH:mm) |
|
||||
| today_heat_runtime | Number:Time | The total number of minutes of heating run-time today |
|
||||
| today_cool_runtime | Number:Time | The total number of minutes of cooling run-time today |
|
||||
| yesterday_heat_runtime | Number:Time | The total number of minutes of heating run-time yesterday |
|
||||
| yesterday_cool_runtime | Number:Time | The total number of minutes of cooling run-time yesterday |
|
||||
|
||||
## Full Example
|
||||
|
||||
@ -145,6 +148,9 @@ Number:Time Therm_todaycool "Today's Cooling Runtime [%d %unit%]" { channe
|
||||
Number:Time Therm_yesterdayheat "Yesterday's Heating Runtime [%d %unit%]" { channel="radiothermostat:rtherm:mytherm1:yesterday_heat_runtime" }
|
||||
Number:Time Therm_yesterdaycool "Yesterday's Cooling Runtime [%d %unit%]" { channel="radiothermostat:rtherm:mytherm1:yesterday_cool_runtime" }
|
||||
|
||||
// Override the thermostat's temperature reading with a value from an external sensor, set to -1 to revert to internal temperature mode
|
||||
Number:Temperature Therm_Rtemp "Remote Temperature [%d]" <temperature> { channel="radiothermostat:rtherm:mytherm1:remote_temp" }
|
||||
|
||||
// A virtual switch used to trigger a rule to send a json command to the thermostat
|
||||
Switch Therm_mysetting "Send my preferred setting"
|
||||
```
|
||||
@ -167,9 +173,12 @@ sitemap radiotherm label="My Thermostat" {
|
||||
Text item=Therm_Override icon="smoke"
|
||||
Switch item=Therm_Hold icon="smoke"
|
||||
|
||||
// Example of overriding the thermostat's temperature reading
|
||||
Switch item=Therm_Rtemp label="Remote Temp" icon="temperature" mappings=[60="60", 75="75", 80="80", -1="Reset"]
|
||||
|
||||
// Virtual switch/button to trigger a rule to send a custom command
|
||||
// The ON value displays in the button
|
||||
Switch item=Therm_mysetting mappings=[ON="Heat, 58, hold"]
|
||||
Switch item=Therm_mysetting mappings=[ON="Heat, 68, hold"]
|
||||
|
||||
Text item=Therm_Day
|
||||
Text item=Therm_Hour
|
||||
@ -198,6 +207,6 @@ then
|
||||
}
|
||||
// JSON to send directly to the thermostat's '/tstat' endpoint
|
||||
// See RadioThermostat_CT50_Honeywell_Wifi_API_V1.3.pdf for more detail
|
||||
actions.sendRawCommand('{"hold":1, "t_heat":' + "58" + ', "tmode":1}')
|
||||
actions.sendRawCommand('{"hold":1, "t_heat":' + "68" + ', "tmode":1}')
|
||||
end
|
||||
```
|
||||
|
||||
BIN
bundles/org.openhab.binding.radiothermostat/doc/index.jpg
Normal file
BIN
bundles/org.openhab.binding.radiothermostat/doc/index.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -47,6 +47,7 @@ public class RadioThermostatBindingConstants {
|
||||
public static final String DEFAULT_RESOURCE = "tstat";
|
||||
public static final String RUNTIME_RESOURCE = "tstat/datalog";
|
||||
public static final String HUMIDITY_RESOURCE = "tstat/humidity";
|
||||
public static final String REMOTE_TEMP_RESOURCE = "tstat/remote_temp";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_RTHERM = new ThingTypeUID(BINDING_ID, "rtherm");
|
||||
@ -70,11 +71,12 @@ public class RadioThermostatBindingConstants {
|
||||
public static final String TODAY_COOL_RUNTIME = "today_cool_runtime";
|
||||
public static final String YESTERDAY_HEAT_RUNTIME = "yesterday_heat_runtime";
|
||||
public static final String YESTERDAY_COOL_RUNTIME = "yesterday_cool_runtime";
|
||||
public static final String REMOTE_TEMP = "remote_temp";
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_RTHERM);
|
||||
public static final Set<String> SUPPORTED_CHANNEL_IDS = Stream.of(TEMPERATURE, HUMIDITY, MODE, FAN_MODE,
|
||||
PROGRAM_MODE, SET_POINT, OVERRIDE, HOLD, STATUS, FAN_STATUS, DAY, HOUR, MINUTE, DATE_STAMP,
|
||||
TODAY_HEAT_RUNTIME, TODAY_COOL_RUNTIME, YESTERDAY_HEAT_RUNTIME, YESTERDAY_COOL_RUNTIME)
|
||||
TODAY_HEAT_RUNTIME, TODAY_COOL_RUNTIME, YESTERDAY_HEAT_RUNTIME, YESTERDAY_COOL_RUNTIME, REMOTE_TEMP)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// Units of measurement of the data delivered by the API
|
||||
|
||||
@ -105,10 +105,11 @@ public class RadioThermostatConnector {
|
||||
*
|
||||
* @param the JSON attribute key for the value to be updated
|
||||
* @param the value to be updated in the thermostat
|
||||
* @param the end point URI to use for the command
|
||||
* @return the JSON response string from the thermostat
|
||||
*/
|
||||
public String sendCommand(String cmdKey, @Nullable String cmdVal) {
|
||||
return sendCommand(cmdKey, cmdVal, null);
|
||||
public String sendCommand(String cmdKey, @Nullable String cmdVal, String resource) {
|
||||
return sendCommand(cmdKey, cmdVal, null, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,12 +118,14 @@ public class RadioThermostatConnector {
|
||||
* @param the JSON attribute key for the value to be updated
|
||||
* @param the value to be updated in the thermostat
|
||||
* @param JSON string to send directly to the thermostat instead of a key/value pair
|
||||
* @param the end point URI to use for the command
|
||||
* @return the JSON response string from the thermostat
|
||||
*/
|
||||
public String sendCommand(@Nullable String cmdKey, @Nullable String cmdVal, @Nullable String cmdJson) {
|
||||
public String sendCommand(@Nullable String cmdKey, @Nullable String cmdVal, @Nullable String cmdJson,
|
||||
String resource) {
|
||||
// if we got a cmdJson string send that, otherwise build the json from the key and val params
|
||||
String postJson = cmdJson != null ? cmdJson : "{\"" + cmdKey + "\":" + cmdVal + "}";
|
||||
String urlStr = buildRequestURL(DEFAULT_RESOURCE);
|
||||
String urlStr = buildRequestURL(resource);
|
||||
|
||||
String output = "";
|
||||
|
||||
|
||||
@ -81,11 +81,12 @@ public class RadioThermostatDiscoveryService extends AbstractDiscoveryService {
|
||||
TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
|
||||
ScheduledFuture<?> scheduledFuture = this.scheduledFuture;
|
||||
if (scheduledFuture != null) {
|
||||
scheduledFuture.cancel(true);
|
||||
this.scheduledFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PointType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@ -216,7 +217,7 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
}
|
||||
|
||||
public void handleRawCommand(@Nullable String rawCommand) {
|
||||
connector.sendCommand(null, null, rawCommand);
|
||||
connector.sendCommand(null, null, rawCommand, DEFAULT_RESOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -226,21 +227,19 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
} else {
|
||||
Integer cmdInt = -1;
|
||||
String cmdStr = command.toString();
|
||||
if (cmdStr != null) {
|
||||
try {
|
||||
// parse out an Integer from the string
|
||||
// ie '70.5 F' becomes 70, also handles negative numbers
|
||||
cmdInt = NumberFormat.getInstance().parse(cmdStr).intValue();
|
||||
} catch (ParseException e) {
|
||||
logger.debug("Command: {} -> Not an integer", cmdStr);
|
||||
}
|
||||
try {
|
||||
// parse out an Integer from the string
|
||||
// ie '70.5 F' becomes 70, also handles negative numbers
|
||||
cmdInt = NumberFormat.getInstance().parse(cmdStr).intValue();
|
||||
} catch (ParseException e) {
|
||||
logger.debug("Command: {} -> Not an integer", cmdStr);
|
||||
}
|
||||
|
||||
switch (channelUID.getId()) {
|
||||
case MODE:
|
||||
// only do if commanded mode is different than current mode
|
||||
if (!cmdInt.equals(rthermData.getThermostatData().getMode())) {
|
||||
connector.sendCommand("tmode", cmdStr);
|
||||
connector.sendCommand("tmode", cmdStr, DEFAULT_RESOURCE);
|
||||
|
||||
// set the new operating mode, reset everything else,
|
||||
// because refreshing the tstat data below is really slow.
|
||||
@ -253,26 +252,26 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
rthermData.getThermostatData().setProgramMode(-1);
|
||||
updateChannel(PROGRAM_MODE, rthermData);
|
||||
|
||||
// now just trigger a refresh of the thermost to get the new active setpoint
|
||||
// now just trigger a refresh of the thermostat to get the new active setpoint
|
||||
// this takes a while for the JSON request to complete (async).
|
||||
connector.getAsyncThermostatData(DEFAULT_RESOURCE);
|
||||
}
|
||||
break;
|
||||
case FAN_MODE:
|
||||
rthermData.getThermostatData().setFanMode(cmdInt);
|
||||
connector.sendCommand("fmode", cmdStr);
|
||||
connector.sendCommand("fmode", cmdStr, DEFAULT_RESOURCE);
|
||||
break;
|
||||
case PROGRAM_MODE:
|
||||
rthermData.getThermostatData().setProgramMode(cmdInt);
|
||||
connector.sendCommand("program_mode", cmdStr);
|
||||
connector.sendCommand("program_mode", cmdStr, DEFAULT_RESOURCE);
|
||||
break;
|
||||
case HOLD:
|
||||
if (command instanceof OnOffType && command == OnOffType.ON) {
|
||||
rthermData.getThermostatData().setHold(1);
|
||||
connector.sendCommand("hold", "1");
|
||||
connector.sendCommand("hold", "1", DEFAULT_RESOURCE);
|
||||
} else if (command instanceof OnOffType && command == OnOffType.OFF) {
|
||||
rthermData.getThermostatData().setHold(0);
|
||||
connector.sendCommand("hold", "0");
|
||||
connector.sendCommand("hold", "0", DEFAULT_RESOURCE);
|
||||
}
|
||||
break;
|
||||
case SET_POINT:
|
||||
@ -287,7 +286,16 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
// don't do anything if we are not in heat or cool mode
|
||||
break;
|
||||
}
|
||||
connector.sendCommand(cmdKey, cmdInt.toString());
|
||||
connector.sendCommand(cmdKey, cmdInt.toString(), DEFAULT_RESOURCE);
|
||||
break;
|
||||
case REMOTE_TEMP:
|
||||
if (cmdInt != -1) {
|
||||
QuantityType<?> remoteTemp = ((QuantityType<Temperature>) command)
|
||||
.toUnit(ImperialUnits.FAHRENHEIT);
|
||||
connector.sendCommand("rem_temp", String.valueOf(remoteTemp.intValue()), REMOTE_TEMP_RESOURCE);
|
||||
} else {
|
||||
connector.sendCommand("rem_mode", "0", REMOTE_TEMP_RESOURCE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.warn("Unsupported command: {}", command.toString());
|
||||
@ -320,7 +328,10 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
updateAllChannels();
|
||||
break;
|
||||
case HUMIDITY_RESOURCE:
|
||||
rthermData.setHumidity(gson.fromJson(evtVal, RadioThermostatHumidityDTO.class).getHumidity());
|
||||
RadioThermostatHumidityDTO dto = gson.fromJson(evtVal, RadioThermostatHumidityDTO.class);
|
||||
if (dto != null) {
|
||||
rthermData.setHumidity(dto.getHumidity());
|
||||
}
|
||||
updateChannel(HUMIDITY, rthermData);
|
||||
break;
|
||||
case RUNTIME_RESOURCE:
|
||||
@ -382,7 +393,7 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
|
||||
/**
|
||||
* Update a given channelId from the thermostat data
|
||||
*
|
||||
*
|
||||
* @param the channel id to be updated
|
||||
* @param data the RadioThermostat dto
|
||||
* @return the value to be set in the state
|
||||
@ -456,7 +467,7 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe
|
||||
|
||||
/**
|
||||
* Build a list of fan modes based on what model thermostat is used
|
||||
*
|
||||
*
|
||||
* @return list of state options for thermostat fan modes
|
||||
*/
|
||||
private List<StateOption> getFanModeOptions() {
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
<channel id="hold" typeId="hold"/>
|
||||
<channel id="status" typeId="status"/>
|
||||
<channel id="fan_status" typeId="fan_status"/>
|
||||
<channel id="remote_temp" typeId="remote_temp"/>
|
||||
<channel id="day" typeId="t_day"/>
|
||||
<channel id="hour" typeId="t_hour"/>
|
||||
<channel id="minute" typeId="t_minute"/>
|
||||
@ -157,6 +158,14 @@
|
||||
<state min="0" max="2" pattern="%d"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="remote_temp" advanced="true">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Remote Temperature</label>
|
||||
<description>The remote temperature takes the place of the ambient temperature as read by the local thermostat
|
||||
temperature sensor</description>
|
||||
<state pattern="%d %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="t_day" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Day</label>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user