Skip to content

Commit

Permalink
[netatmo] Avoid multiple device data reading at startup
Browse files Browse the repository at this point in the history
Fix openhab#5440

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
  • Loading branch information
lolodomo committed Jul 10, 2020
1 parent 09e4b41 commit 247a19d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ public void expireData() {
ZonedDateTime now = ZonedDateTime.now().minus(this.dataValidityPeriod, ChronoUnit.MILLIS);
dataTimeStamp = now.toInstant().toEpochMilli();
}

public boolean isSearchingRefreshInterval() {
return searchRefreshInterval && dataTimestamp0 != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public abstract class NetatmoDeviceHandler<DEVICE> extends AbstractNetatmoThingH
private static final int DEFAULT_REFRESH_INTERVAL = 300000;

private final Logger logger = LoggerFactory.getLogger(NetatmoDeviceHandler.class);
private final Object updateLock = new Object();
private @Nullable ScheduledFuture<?> refreshJob;
private @Nullable RefreshStrategy refreshStrategy;
private @Nullable DEVICE device;
Expand All @@ -79,7 +80,7 @@ private void scheduleRefreshJob() {
long delay = strategy.nextRunDelayInS();
logger.debug("Scheduling update channel thread in {} s", delay);
refreshJob = scheduler.schedule(() -> {
updateChannels();
updateChannels(false);
ScheduledFuture<?> job = refreshJob;
if (job != null) {
job.cancel(false);
Expand All @@ -106,53 +107,62 @@ protected void updateProperties(DEVICE deviceData) {

@Override
protected void updateChannels() {
RefreshStrategy strategy = refreshStrategy;
if (strategy != null) {
logger.debug("Data aged of {} s", strategy.dataAge() / 1000);
if (strategy.isDataOutdated()) {
logger.debug("Trying to update channels on device {}", getId());
childs.clear();

Optional<DEVICE> newDeviceReading = Optional.empty();
try {
newDeviceReading = updateReadings();
} catch (RetrofitError e) {
if (logger.isDebugEnabled()) {
// we also attach the stack trace
logger.error("Unable to connect Netatmo API : {}", e.getMessage(), e);
updateChannels(true);
}

private void updateChannels(boolean requireDefinedRefreshInterval) {
// Avoid concurrent data readings
synchronized (updateLock) {
RefreshStrategy strategy = refreshStrategy;
if (strategy != null) {
logger.debug("Data aged of {} s", strategy.dataAge() / 1000);
boolean dataOutdated = (requireDefinedRefreshInterval && strategy.isSearchingRefreshInterval()) ? false
: strategy.isDataOutdated();
if (dataOutdated) {
logger.debug("Trying to update channels on device {}", getId());
childs.clear();

Optional<DEVICE> newDeviceReading = Optional.empty();
try {
newDeviceReading = updateReadings();
} catch (RetrofitError e) {
if (logger.isDebugEnabled()) {
// we also attach the stack trace
logger.error("Unable to connect Netatmo API : {}", e.getMessage(), e);
} else {
logger.error("Unable to connect Netatmo API : {}", e.getMessage());
}
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Unable to connect Netatmo API : " + e.getLocalizedMessage());
}
if (newDeviceReading.isPresent()) {
updateStatus(ThingStatus.ONLINE);
logger.debug("Successfully updated device {} readings! Now updating channels", getId());
DEVICE theDevice = newDeviceReading.get();
this.device = theDevice;
updateProperties(theDevice);
getDataTimestamp().ifPresent(dataTimeStamp -> {
strategy.setDataTimeStamp(dataTimeStamp, timeZoneProvider.getTimeZone());
});
getRadioHelper().ifPresent(helper -> helper.setModule(theDevice));
getBridgeHandler().ifPresent(handler -> {
handler.checkForNewThings(theDevice);
});
} else {
logger.error("Unable to connect Netatmo API : {}", e.getMessage());
logger.debug("Failed to update device {} readings! Skip updating channels", getId());
}
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Unable to connect Netatmo API : " + e.getLocalizedMessage());
}
if (newDeviceReading.isPresent()) {
updateStatus(ThingStatus.ONLINE);
logger.debug("Successfully updated device {} readings! Now updating channels", getId());
DEVICE theDevice = newDeviceReading.get();
this.device = theDevice;
updateProperties(theDevice);
getDataTimestamp().ifPresent(dataTimeStamp -> {
strategy.setDataTimeStamp(dataTimeStamp, timeZoneProvider.getTimeZone());
});
getRadioHelper().ifPresent(helper -> helper.setModule(theDevice));
getBridgeHandler().ifPresent(handler -> {
handler.checkForNewThings(theDevice);
// Be sure that all channels for the modules will be updated with refreshed data
childs.forEach((childId, moduleData) -> {
findNAThing(childId).map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
naChildModule.setRefreshRequired(true);
});
});
} else {
logger.debug("Failed to update device {} readings! Skip updating channels", getId());
logger.debug("Data still valid for device {}", getId());
}
// Be sure that all channels for the modules will be updated with refreshed data
childs.forEach((childId, moduleData) -> {
findNAThing(childId).map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
naChildModule.setRefreshRequired(true);
});
});
} else {
logger.debug("Data still valid for device {}", getId());
super.updateChannels();
updateChildModules();
}
super.updateChannels();
updateChildModules();
}
}

Expand Down

0 comments on commit 247a19d

Please sign in to comment.