[boschindego] Refresh cutting times right after next planned cutting (#13158)
* Refresh cutting times right after next planned cutting * Cancel cutting time future unconditionally Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
parent
24e9228699
commit
67006de606
@ -16,6 +16,7 @@ import static org.openhab.binding.boschindego.internal.BoschIndegoBindingConstan
|
|||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -71,6 +72,7 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
private @NonNullByDefault({}) IndegoController controller;
|
private @NonNullByDefault({}) IndegoController controller;
|
||||||
private @Nullable ScheduledFuture<?> statePollFuture;
|
private @Nullable ScheduledFuture<?> statePollFuture;
|
||||||
private @Nullable ScheduledFuture<?> cuttingTimeMapPollFuture;
|
private @Nullable ScheduledFuture<?> cuttingTimeMapPollFuture;
|
||||||
|
private @Nullable ScheduledFuture<?> cuttingTimeFuture;
|
||||||
private boolean propertiesInitialized;
|
private boolean propertiesInitialized;
|
||||||
private Optional<Integer> previousStateCode = Optional.empty();
|
private Optional<Integer> previousStateCode = Optional.empty();
|
||||||
|
|
||||||
@ -124,6 +126,11 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
pollFuture.cancel(true);
|
pollFuture.cancel(true);
|
||||||
}
|
}
|
||||||
this.cuttingTimeMapPollFuture = null;
|
this.cuttingTimeMapPollFuture = null;
|
||||||
|
pollFuture = this.cuttingTimeFuture;
|
||||||
|
if (pollFuture != null) {
|
||||||
|
pollFuture.cancel(true);
|
||||||
|
}
|
||||||
|
this.cuttingTimeFuture = null;
|
||||||
|
|
||||||
scheduler.execute(() -> {
|
scheduler.execute(() -> {
|
||||||
try {
|
try {
|
||||||
@ -249,6 +256,17 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshCuttingTimesWithExceptionHandling() {
|
||||||
|
try {
|
||||||
|
refreshCuttingTimes();
|
||||||
|
} catch (IndegoAuthenticationException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||||
|
"@text/offline.comm-error.authentication-failure");
|
||||||
|
} catch (IndegoException e) {
|
||||||
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshCuttingTimes() throws IndegoAuthenticationException, IndegoException {
|
private void refreshCuttingTimes() throws IndegoAuthenticationException, IndegoException {
|
||||||
if (isLinked(LAST_CUTTING)) {
|
if (isLinked(LAST_CUTTING)) {
|
||||||
Instant lastCutting = controller.getPredictiveLastCutting();
|
Instant lastCutting = controller.getPredictiveLastCutting();
|
||||||
@ -260,17 +278,39 @@ public class BoschIndegoHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelCuttingTimeRefresh();
|
||||||
if (isLinked(NEXT_CUTTING)) {
|
if (isLinked(NEXT_CUTTING)) {
|
||||||
Instant nextCutting = controller.getPredictiveNextCutting();
|
Instant nextCutting = controller.getPredictiveNextCutting();
|
||||||
if (nextCutting != null) {
|
if (nextCutting != null) {
|
||||||
updateState(NEXT_CUTTING,
|
updateState(NEXT_CUTTING,
|
||||||
new DateTimeType(ZonedDateTime.ofInstant(nextCutting, timeZoneProvider.getTimeZone())));
|
new DateTimeType(ZonedDateTime.ofInstant(nextCutting, timeZoneProvider.getTimeZone())));
|
||||||
|
scheduleCuttingTimesRefresh(nextCutting);
|
||||||
} else {
|
} else {
|
||||||
updateState(NEXT_CUTTING, UnDefType.UNDEF);
|
updateState(NEXT_CUTTING, UnDefType.UNDEF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancelCuttingTimeRefresh() {
|
||||||
|
ScheduledFuture<?> cuttingTimeFuture = this.cuttingTimeFuture;
|
||||||
|
if (cuttingTimeFuture != null) {
|
||||||
|
// Do not interrupt as we might be running within that job.
|
||||||
|
cuttingTimeFuture.cancel(false);
|
||||||
|
this.cuttingTimeFuture = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleCuttingTimesRefresh(Instant nextCutting) {
|
||||||
|
// Schedule additional update right after next planned cutting. This ensures a faster update
|
||||||
|
// in case the next cutting will be postponed (for example due to weather conditions).
|
||||||
|
long secondsUntilNextCutting = Instant.now().until(nextCutting, ChronoUnit.SECONDS) + 2;
|
||||||
|
if (secondsUntilNextCutting > 0) {
|
||||||
|
logger.debug("Scheduling fetching of cutting times in {} seconds", secondsUntilNextCutting);
|
||||||
|
this.cuttingTimeFuture = scheduler.schedule(this::refreshCuttingTimesWithExceptionHandling,
|
||||||
|
secondsUntilNextCutting, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshCuttingTimesAndMapWithExceptionHandling() {
|
private void refreshCuttingTimesAndMapWithExceptionHandling() {
|
||||||
try {
|
try {
|
||||||
refreshCuttingTimes();
|
refreshCuttingTimes();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user