2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.netatmo.internal;
15 import java.time.ZoneId;
16 import java.time.ZonedDateTime;
17 import java.time.temporal.ChronoUnit;
18 import java.util.Calendar;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * {@link RefreshStrategy} is the class used to embed the refreshing
27 * needs calculation for devices
29 * @author Gaƫl L'hopital - Initial contribution
33 public class RefreshStrategy {
35 private Logger logger = LoggerFactory.getLogger(RefreshStrategy.class);
37 private static final int DEFAULT_DELAY = 30; // in seconds
38 private static final int SEARCH_REFRESH_INTERVAL = 120; // in seconds
39 private int dataValidityPeriod;
40 private long dataTimeStamp;
41 private boolean searchRefreshInterval;
43 private Integer dataTimestamp0;
45 // By default we create dataTimeStamp to be outdated
46 // A null or negative value for dataValidityPeriod will trigger an automatic search of the validity period
47 public RefreshStrategy(int dataValidityPeriod) {
48 if (dataValidityPeriod <= 0) {
49 this.dataValidityPeriod = 0;
50 this.searchRefreshInterval = true;
51 logger.debug("Data validity period search...");
53 this.dataValidityPeriod = dataValidityPeriod;
54 this.searchRefreshInterval = false;
55 logger.debug("Data validity period set to {} ms", this.dataValidityPeriod);
60 @SuppressWarnings("null")
61 public void setDataTimeStamp(Integer dataTimestamp, ZoneId zoneId) {
62 if (searchRefreshInterval) {
63 if (dataTimestamp0 == null) {
64 dataTimestamp0 = dataTimestamp;
65 logger.debug("First data timestamp is {}", dataTimestamp0);
66 } else if (dataTimestamp.intValue() > dataTimestamp0.intValue()) {
67 dataValidityPeriod = (dataTimestamp.intValue() - dataTimestamp0.intValue()) * 1000;
68 searchRefreshInterval = false;
69 logger.debug("Data validity period found : {} ms", this.dataValidityPeriod);
71 logger.debug("Data validity period not yet found - data timestamp unchanged");
74 this.dataTimeStamp = ChannelTypeUtils.toZonedDateTime(dataTimestamp, zoneId).toInstant().toEpochMilli();
77 public long dataAge() {
78 long now = Calendar.getInstance().getTimeInMillis();
79 return now - dataTimeStamp;
82 public boolean isDataOutdated() {
83 return dataAge() >= dataValidityPeriod;
86 public long nextRunDelayInS() {
87 return searchRefreshInterval ? SEARCH_REFRESH_INTERVAL
88 : Math.max(0, (dataValidityPeriod - dataAge())) / 1000 + DEFAULT_DELAY;
91 public void expireData() {
92 ZonedDateTime now = ZonedDateTime.now().minus(this.dataValidityPeriod, ChronoUnit.MILLIS);
93 dataTimeStamp = now.toInstant().toEpochMilli();
96 public boolean isSearchingRefreshInterval() {
97 return searchRefreshInterval && dataTimestamp0 != null;