Skip to content

Commit

Permalink
[netatmo] Null annotations Part 2 of 3 (openhab#8019)
Browse files Browse the repository at this point in the history
Related to openhab#7913

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
Signed-off-by: Daan Meijer <daan@studioseptember.nl>
  • Loading branch information
lolodomo authored and DaanMeijer committed Sep 1, 2020
1 parent 59b3923 commit 35b73db
Show file tree
Hide file tree
Showing 14 changed files with 236 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
*/
package org.openhab.binding.netatmo.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* This class holds various unit/measurement conversion methods
*
* @author Gaël L'hopital - Initial contribution
* @author Rob Nielsen - updated heat index
*/
@NonNullByDefault
public class WeatherUtils {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,13 @@ protected void updateProperties(Integer firmware, String modelId) {
public void updateMeasurements() {
}

public void getMeasurements(NetatmoBridgeHandler handler, String device, @Nullable String module, String scale,
List<String> types, List<String> channels, Map<String, Float> channelMeasurements) {
public void getMeasurements(String device, @Nullable String module, String scale, List<String> types,
List<String> channels, Map<String, Float> channelMeasurements) {
NetatmoBridgeHandler handler = getBridgeHandler();
if (handler == null) {
return;
}

if (types.size() != channels.size()) {
throw new IllegalArgumentException("types and channels lists are different sizes.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.util.List;
import java.util.Optional;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.types.State;
import org.openhab.binding.netatmo.internal.ChannelTypeUtils;
Expand All @@ -33,8 +35,9 @@
* @author Gaël L'hopital - Initial contribution
*
*/
@NonNullByDefault
public class MeasurableChannels {
protected NAMeasureResponse measures;
protected @Nullable NAMeasureResponse measures;
protected List<String> measuredChannels = new ArrayList<>();

/*
Expand All @@ -59,9 +62,10 @@ protected void removeChannel(ChannelUID channelUID) {

protected Optional<State> getNAThingProperty(String channelId) {
int index = measuredChannels.indexOf(channelId);
if (index != -1 && measures != null) {
if (!measures.getBody().isEmpty()) {
List<List<Float>> valueList = measures.getBody().get(0).getValue();
NAMeasureResponse theMeasures = measures;
if (index != -1 && theMeasures != null) {
if (!theMeasures.getBody().isEmpty()) {
List<List<Float>> valueList = theMeasures.getBody().get(0).getValue();
if (!valueList.isEmpty()) {
List<Float> values = valueList.get(0);
if (values.size() >= index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ public void initialize() {

private void connectionSucceed() {
updateStatus(ThingStatus.ONLINE);
WelcomeWebHookServlet webHookServlet = this.webHookServlet;
WelcomeWebHookServlet servlet = webHookServlet;
String webHookURI = getWebHookURI();
WelcomeApi welcomeApi = getWelcomeApi();
if (welcomeApi != null && webHookServlet != null && webHookURI != null) {
webHookServlet.activate(this);
if (welcomeApi != null && servlet != null && webHookURI != null) {
servlet.activate(this);
logger.debug("Setting up Netatmo Welcome WebHook");
welcomeApi.addwebhook(webHookURI, WEBHOOK_APP);
}
Expand Down Expand Up @@ -226,39 +226,39 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}

public @Nullable PartnerApi getPartnerApi() {
APIMap apiMap = this.apiMap;
return apiMap != null ? (PartnerApi) apiMap.get(PartnerApi.class) : null;
APIMap map = apiMap;
return map != null ? (PartnerApi) map.get(PartnerApi.class) : null;
}

private @Nullable StationApi getStationApi() {
APIMap apiMap = this.apiMap;
return apiMap != null ? (StationApi) apiMap.get(StationApi.class) : null;
APIMap map = apiMap;
return map != null ? (StationApi) map.get(StationApi.class) : null;
}

private @Nullable HealthyhomecoachApi getHomeCoachApi() {
APIMap apiMap = this.apiMap;
return apiMap != null ? (HealthyhomecoachApi) apiMap.get(HealthyhomecoachApi.class) : null;
APIMap map = apiMap;
return map != null ? (HealthyhomecoachApi) map.get(HealthyhomecoachApi.class) : null;
}

public @Nullable ThermostatApi getThermostatApi() {
APIMap apiMap = this.apiMap;
return apiMap != null ? (ThermostatApi) apiMap.get(ThermostatApi.class) : null;
APIMap map = apiMap;
return map != null ? (ThermostatApi) map.get(ThermostatApi.class) : null;
}

public @Nullable WelcomeApi getWelcomeApi() {
APIMap apiMap = this.apiMap;
return apiMap != null ? (WelcomeApi) apiMap.get(WelcomeApi.class) : null;
APIMap map = apiMap;
return map != null ? (WelcomeApi) map.get(WelcomeApi.class) : null;
}

@Override
public void dispose() {
logger.debug("Running dispose()");

WelcomeWebHookServlet webHookServlet = this.webHookServlet;
WelcomeWebHookServlet servlet = webHookServlet;
WelcomeApi welcomeApi = getWelcomeApi();
if (welcomeApi != null && webHookServlet != null && getWebHookURI() != null) {
if (welcomeApi != null && servlet != null && getWebHookURI() != null) {
logger.debug("Releasing Netatmo Welcome WebHook");
webHookServlet.deactivate();
servlet.deactivate();
welcomeApi.dropwebhook(WEBHOOK_APP);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.i18n.TimeZoneProvider;
import org.eclipse.smarthome.core.library.types.DecimalType;
Expand All @@ -47,16 +47,16 @@
*
* @author Gaël L'hopital - Initial contribution
*/
@NonNullByDefault
public abstract class NetatmoDeviceHandler<DEVICE> extends AbstractNetatmoThingHandler {

private static final int MIN_REFRESH_INTERVAL = 2000;
private static final int DEFAULT_REFRESH_INTERVAL = 300000;

private Logger logger = LoggerFactory.getLogger(NetatmoDeviceHandler.class);
private ScheduledFuture<?> refreshJob;
private RefreshStrategy refreshStrategy;
@Nullable
protected DEVICE device;
private final Logger logger = LoggerFactory.getLogger(NetatmoDeviceHandler.class);
private @Nullable ScheduledFuture<?> refreshJob;
private @Nullable RefreshStrategy refreshStrategy;
protected @Nullable DEVICE device;
protected Map<String, Object> childs = new ConcurrentHashMap<>();

public NetatmoDeviceHandler(Thing thing, final TimeZoneProvider timeZoneProvider) {
Expand All @@ -71,13 +71,18 @@ protected void initializeThing() {
}

private void scheduleRefreshJob() {
long delay = refreshStrategy.nextRunDelayInS();
RefreshStrategy strategy = refreshStrategy;
if (strategy == null) {
return;
}
long delay = strategy.nextRunDelayInS();
logger.debug("Scheduling update channel thread in {} s", delay);
refreshJob = scheduler.schedule(() -> {
updateChannels();
if (refreshJob != null && !refreshJob.isCancelled()) {
ScheduledFuture<?> job = refreshJob;
if (job != null) {
logger.debug("cancel refresh job");
refreshJob.cancel(false);
job.cancel(false);
refreshJob = null;
}
scheduleRefreshJob();
Expand All @@ -87,9 +92,10 @@ private void scheduleRefreshJob() {
@Override
public void dispose() {
logger.debug("Running dispose()");
if (refreshJob != null && !refreshJob.isCancelled()) {
ScheduledFuture<?> job = refreshJob;
if (job != null) {
logger.debug("cancel refresh job");
refreshJob.cancel(true);
job.cancel(true);
refreshJob = null;
}
}
Expand All @@ -101,12 +107,14 @@ protected void updateProperties(DEVICE deviceData) {

@Override
protected void updateChannels() {
if (refreshStrategy != null) {
logger.debug("Data aged of {} s", refreshStrategy.dataAge() / 1000);
if (refreshStrategy.isDataOutdated()) {
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();

@Nullable
DEVICE newDeviceReading = null;
try {
newDeviceReading = updateReadings();
Expand All @@ -120,31 +128,33 @@ protected void updateChannels() {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Unable to connect Netatmo API : " + e.getLocalizedMessage());
}
NetatmoBridgeHandler bridgeHandler = getBridgeHandler();
if (newDeviceReading != null) {
updateStatus(ThingStatus.ONLINE);
logger.debug("Successfully updated device {} readings! Now updating channels", getId());
DEVICE device = newDeviceReading;
this.device = device;
updateProperties(device);
DEVICE theDevice = newDeviceReading;
this.device = theDevice;
updateProperties(theDevice);
Integer dataTimeStamp = getDataTimestamp();
if (dataTimeStamp != null) {
refreshStrategy.setDataTimeStamp(dataTimeStamp, timeZoneProvider.getTimeZone());
strategy.setDataTimeStamp(dataTimeStamp, timeZoneProvider.getTimeZone());
}
radioHelper.ifPresent(helper -> helper.setModule(device));
NetatmoBridgeHandler handler = getBridgeHandler();
if (handler != null) {
handler.checkForNewThings(newDeviceReading);
radioHelper.ifPresent(helper -> helper.setModule(theDevice));
if (bridgeHandler != null) {
bridgeHandler.checkForNewThings(newDeviceReading);
}
} else {
logger.debug("Failed to update device {} readings! Skip updating channels", getId());
}
// Be sure that all channels for the modules will be updated with refreshed data
childs.forEach((childId, moduleData) -> {
Optional<AbstractNetatmoThingHandler> childHandler = getBridgeHandler().findNAThing(childId);
childHandler.map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
naChildModule.setRefreshRequired(true);
if (bridgeHandler != null) {
childs.forEach((childId, moduleData) -> {
Optional<AbstractNetatmoThingHandler> childHandler = bridgeHandler.findNAThing(childId);
childHandler.map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
naChildModule.setRefreshRequired(true);
});
});
});
}
} else {
logger.debug("Data still valid for device {}", getId());
}
Expand All @@ -154,21 +164,23 @@ protected void updateChannels() {
}

@Override
protected State getNAThingProperty(@NonNull String channelId) {
protected State getNAThingProperty(String channelId) {
try {
@Nullable
DEVICE theDevice = device;
switch (channelId) {
case CHANNEL_LAST_STATUS_STORE:
if (device != null) {
Method getLastStatusStore = device.getClass().getMethod("getLastStatusStore");
Integer lastStatusStore = (Integer) getLastStatusStore.invoke(device);
if (theDevice != null) {
Method getLastStatusStore = theDevice.getClass().getMethod("getLastStatusStore");
Integer lastStatusStore = (Integer) getLastStatusStore.invoke(theDevice);
return ChannelTypeUtils.toDateTimeType(lastStatusStore, timeZoneProvider.getTimeZone());
} else {
return UnDefType.UNDEF;
}
case CHANNEL_LOCATION:
if (device != null) {
Method getPlace = device.getClass().getMethod("getPlace");
NAPlace place = (NAPlace) getPlace.invoke(device);
if (theDevice != null) {
Method getPlace = theDevice.getClass().getMethod("getPlace");
NAPlace place = (NAPlace) getPlace.invoke(theDevice);
PointType point = new PointType(new DecimalType(place.getLocation().get(1)),
new DecimalType(place.getLocation().get(0)));
if (place.getAltitude() != null) {
Expand All @@ -188,14 +200,17 @@ protected State getNAThingProperty(@NonNull String channelId) {
}

private void updateChildModules() {
logger.debug("Updating child modules of {}", getId());
childs.forEach((childId, moduleData) -> {
Optional<AbstractNetatmoThingHandler> childHandler = getBridgeHandler().findNAThing(childId);
childHandler.map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
logger.debug("Updating child module {}", naChildModule.getId());
naChildModule.updateChannels(moduleData);
NetatmoBridgeHandler bridgeHandler = getBridgeHandler();
if (bridgeHandler != null) {
logger.debug("Updating child modules of {}", getId());
childs.forEach((childId, moduleData) -> {
Optional<AbstractNetatmoThingHandler> childHandler = bridgeHandler.findNAThing(childId);
childHandler.map(NetatmoModuleHandler.class::cast).ifPresent(naChildModule -> {
logger.debug("Updating child module {}", naChildModule.getId());
naChildModule.updateChannels(moduleData);
});
});
});
}
}

/*
Expand Down Expand Up @@ -231,6 +246,9 @@ private void defineRefreshInterval() {
protected abstract @Nullable Integer getDataTimestamp();

public void expireData() {
refreshStrategy.expireData();
RefreshStrategy strategy = refreshStrategy;
if (strategy != null) {
strategy.expireData();
}
}
}
Loading

0 comments on commit 35b73db

Please sign in to comment.