From 6141d69da3f5b4e525b2b4e7b8388da3b40e83eb Mon Sep 17 00:00:00 2001 From: mlobstein Date: Mon, 7 Jun 2021 13:58:19 -0500 Subject: [PATCH] [radiothermostat] Add job to set thermostat clock automatically from the binding (#10819) * add thermostat clock sync job Signed-off-by: Michael Lobstein --- .../README.md | 1 + .../RadioThermostatBindingConstants.java | 2 + .../RadioThermostatConfiguration.java | 1 + .../handler/RadioThermostatHandler.java | 49 ++++++++++++++++++- .../resources/OH-INF/thing/thing-types.xml | 6 ++- 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.radiothermostat/README.md b/bundles/org.openhab.binding.radiothermostat/README.md index e5244c0de..0babb2ce3 100644 --- a/bundles/org.openhab.binding.radiothermostat/README.md +++ b/bundles/org.openhab.binding.radiothermostat/README.md @@ -42,6 +42,7 @@ The thing has a few configuration parameters: | isCT80 | Flag to enable additional features only available on the CT80 thermostat. Optional, the default is false. | | disableLogs | Disable retrieval of run-time logs from the thermostat. Optional, the default is false. | | setpointMode | Controls temporary or absolute setpoint mode. In "temporary" mode the thermostat will temporarily maintain the given setpoint, returning to its program after a time. In "absolute" mode the thermostat will ignore its program maintaining the given setpoint. | +| clockSync | Flag to enable the binding to sync the internal clock on the thermostat to match the openHAB host's system clock. Use if the thermostat is not setup to connect to the manufacturer's cloud server. Sync occurs at binding startup and every hour thereafter. | ## Channels diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatBindingConstants.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatBindingConstants.java index daf02d99e..8566bab20 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatBindingConstants.java +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatBindingConstants.java @@ -40,6 +40,7 @@ public class RadioThermostatBindingConstants { public static final String LOCAL = "local"; public static final String PROPERTY_IP = "hostName"; public static final String PROPERTY_ISCT80 = "isCT80"; + public static final String JSON_TIME = "{\"day\":%s,\"hour\":%s,\"minute\":%s}"; public static final String KEY_ERROR = "error"; @@ -48,6 +49,7 @@ public class RadioThermostatBindingConstants { 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"; + public static final String TIME_RESOURCE = "tstat/time"; // List of all Thing Type UIDs public static final ThingTypeUID THING_TYPE_RTHERM = new ThingTypeUID(BINDING_ID, "rtherm"); diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatConfiguration.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatConfiguration.java index 926999121..203fccb2b 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatConfiguration.java +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/RadioThermostatConfiguration.java @@ -28,5 +28,6 @@ public class RadioThermostatConfiguration { public @Nullable Integer logRefresh; public boolean isCT80 = false; public boolean disableLogs = false; + public boolean clockSync = false; public String setpointMode = "temporary"; } diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/handler/RadioThermostatHandler.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/handler/RadioThermostatHandler.java index 6ab451829..698efe76e 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/handler/RadioThermostatHandler.java +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/handler/RadioThermostatHandler.java @@ -19,6 +19,7 @@ import java.text.NumberFormat; import java.text.ParseException; import java.time.ZonedDateTime; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -86,11 +87,13 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe private @Nullable ScheduledFuture refreshJob; private @Nullable ScheduledFuture logRefreshJob; + private @Nullable ScheduledFuture clockSyncJob; private int refreshPeriod = DEFAULT_REFRESH_PERIOD; private int logRefreshPeriod = DEFAULT_LOG_REFRESH_PERIOD; private boolean isCT80 = false; private boolean disableLogs = false; + private boolean clockSync = false; private String setpointCmdKeyPrefix = "t_"; public RadioThermostatHandler(Thing thing, RadioThermostatStateDescriptionProvider stateDescriptionProvider, @@ -111,8 +114,9 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe final Integer logRefresh = config.logRefresh; this.isCT80 = config.isCT80; this.disableLogs = config.disableLogs; + this.clockSync = config.clockSync; - if (hostName == null || hostName.equals("")) { + if (hostName == null || "".equals(hostName)) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Thermostat Host Name must be specified"); return; @@ -145,12 +149,18 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe channels.removeIf(c -> (c.getUID().getId().equals(PROGRAM_MODE))); updateThing(editThing().withChannels(channels).build()); } + + updateStatus(ThingStatus.UNKNOWN); + startAutomaticRefresh(); + if (!this.disableLogs || this.isCT80) { startAutomaticLogRefresh(); } - updateStatus(ThingStatus.UNKNOWN); + if (this.clockSync) { + scheduleClockSyncJob(); + } } @Override @@ -174,6 +184,35 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe } } + /** + * Schedule the clock sync job + */ + private void scheduleClockSyncJob() { + ScheduledFuture clockSyncJob = this.clockSyncJob; + if (clockSyncJob == null || clockSyncJob.isCancelled()) { + clockSyncJob = null; + this.clockSyncJob = scheduler.scheduleWithFixedDelay(this::syncThermostatClock, 1, 60, TimeUnit.MINUTES); + } + } + + /** + * Sync the thermostat's clock with the host system clock + */ + private void syncThermostatClock() { + Calendar c = Calendar.getInstance(); + + // The thermostat week starts as Monday = 0, subtract 2 since in standard DoW Monday = 2 + int thermDayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 2; + // Sunday will be -1, so add 7 to make it 6 + if (thermDayOfWeek < 0) { + thermDayOfWeek += 7; + } + + connector.sendCommand(null, null, + String.format(JSON_TIME, thermDayOfWeek, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE)), + TIME_RESOURCE); + } + /** * Start the job to periodically update humidity and runtime date from the thermostat */ @@ -214,6 +253,12 @@ public class RadioThermostatHandler extends BaseThingHandler implements RadioThe logRefreshJob.cancel(true); this.logRefreshJob = null; } + + ScheduledFuture clockSyncJob = this.clockSyncJob; + if (clockSyncJob != null) { + clockSyncJob.cancel(true); + this.clockSyncJob = null; + } } public void handleRawCommand(@Nullable String rawCommand) { diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.radiothermostat/src/main/resources/OH-INF/thing/thing-types.xml index a33622dbd..247f643c0 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.radiothermostat/src/main/resources/OH-INF/thing/thing-types.xml @@ -68,7 +68,11 @@ - + + + Optional Flag to snyc the thermostat's clock with the host system clock + false +