diff --git a/bundles/org.openhab.binding.netatmo/pom.xml b/bundles/org.openhab.binding.netatmo/pom.xml
index b3b13ee0687cc..7e04a27d570b0 100644
--- a/bundles/org.openhab.binding.netatmo/pom.xml
+++ b/bundles/org.openhab.binding.netatmo/pom.xml
@@ -13,75 +13,9 @@
org.openhab.binding.netatmo
openHAB Add-ons :: Bundles :: Netatmo Binding
-
-<<<<<<< Upstream, based on origin/main
-
- org.openhab.binding.netatmo.*
-
-<<<<<<< Upstream, based on origin/main
-
+
-
- org.openhab.osgiify
- org.json.json
- 20131018
- compile
-
-
- com.squareup.okhttp
- okhttp
- 2.7.5
- compile
-
-
- com.google.android
- *
-
-
-
-
- com.squareup.okhttp
- logging-interceptor
- 2.7.5
- compile
-
-
- com.google.android
- *
-
-
-
-
- com.squareup.okio
- okio
- 1.6.0
- compile
-
-
- io.gsonfire
- gson-fire
- 1.8.4
- compile
-
-
- org.apache.oltu.oauth2
- org.apache.oltu.oauth2.client
- 1.0.0
- compile
-
-
- org.apache.oltu.oauth2
- org.apache.oltu.oauth2.common
- 1.0.0
- compile
-
-
- commons-codec
- commons-codec
- 1.8
- compile
-
-
+
com.google.code.gson
gson
2.8.5
@@ -89,37 +23,4 @@
-
-
-
- io.swagger.codegen.v3
- swagger-codegen-maven-plugin
- 3.0.21
-
-
-
- generate
-
-
- https://raw.githubusercontent.com/cbornet/netatmo-swagger-decl/35e27745fb0d432bc6c8b5ec7a83ed2a09944cea/spec/swagger.yaml
- java
- false
- false
-
- src/main/java
- true
- java8-localdatetime
- true
-
-
-
-
-
-
-
-
-=======
->>>>>>> 54453ef Rebase and spotless apply
-=======
->>>>>>> 4201a80 Code cleansing
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/ChannelTypeUtils.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/ChannelTypeUtils.java
deleted file mode 100644
index 909187a1895c2..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/ChannelTypeUtils.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.netatmo.internal;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-
-import javax.measure.Unit;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.core.io.net.http.HttpUtil;
-import org.openhab.core.library.types.DateTimeType;
-import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.library.types.OnOffType;
-import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.library.types.RawType;
-import org.openhab.core.library.types.StringType;
-import org.openhab.core.types.State;
-import org.openhab.core.types.UnDefType;
-
-/**
- * This class holds various channel values conversion methods
- *
- * @author Gaël L'hopital - Initial contribution
- * @author Rob Nielsen - Added day, week, and month measurements to the weather station and modules
- *
- */
-@NonNullByDefault
-public class ChannelTypeUtils {
-
- public static State toStringType(@Nullable String value) {
- return (value == null) ? UnDefType.NULL : new StringType(value);
- }
-
- public static ZonedDateTime toZonedDateTime(Integer netatmoTS, ZoneId zoneId) {
- Instant i = Instant.ofEpochSecond(netatmoTS);
- return ZonedDateTime.ofInstant(i, zoneId);
- }
-
- public static State toDateTimeType(@Nullable Float netatmoTS, ZoneId zoneId) {
- return netatmoTS == null ? UnDefType.NULL : toDateTimeType(toZonedDateTime(netatmoTS.intValue(), zoneId));
- }
-
- public static State toDateTimeType(@Nullable Integer netatmoTS, ZoneId zoneId) {
- return netatmoTS == null ? UnDefType.NULL : toDateTimeType(toZonedDateTime(netatmoTS, zoneId));
- }
-
- public static State toDateTimeType(@Nullable ZonedDateTime zonedDateTime) {
- return (zonedDateTime == null) ? UnDefType.NULL : new DateTimeType(zonedDateTime);
- }
-
- public static State toDecimalType(@Nullable Float value) {
- return (value == null) ? UnDefType.NULL : toDecimalType(new BigDecimal(value));
- }
-
- public static State toDecimalType(@Nullable Integer value) {
- return (value == null) ? UnDefType.NULL : toDecimalType(new BigDecimal(value));
- }
-
- public static State toDecimalType(@Nullable Double value) {
- return (value == null) ? UnDefType.NULL : toDecimalType(new BigDecimal(value));
- }
-
- public static State toDecimalType(float value) {
- return toDecimalType(new BigDecimal(value));
- }
-
- public static State toDecimalType(double value) {
- return toDecimalType(new BigDecimal(value));
- }
-
- public static State toDecimalType(@Nullable BigDecimal decimal) {
- return decimal == null ? UnDefType.NULL : new DecimalType(decimal.setScale(2, RoundingMode.HALF_UP));
- }
-
- public static State toDecimalType(@Nullable String textualDecimal) {
- return textualDecimal == null ? UnDefType.NULL : new DecimalType(textualDecimal);
- }
-
- public static State toOnOffType(@Nullable String yesno) {
- return "on".equalsIgnoreCase(yesno) ? OnOffType.ON : OnOffType.OFF;
- }
-
- public static State toOnOffType(@Nullable Integer value) {
- return value != null ? (value == 1 ? OnOffType.ON : OnOffType.OFF) : UnDefType.UNDEF;
- }
-
- public static State toOnOffType(@Nullable Boolean value) {
- return value != null ? (value ? OnOffType.ON : OnOffType.OFF) : UnDefType.UNDEF;
- }
-
- public static State toQuantityType(@Nullable Float value, Unit> unit) {
- return value == null ? UnDefType.NULL : toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(@Nullable Integer value, Unit> unit) {
- return value == null ? UnDefType.NULL : toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(@Nullable Double value, Unit> unit) {
- return value == null ? UnDefType.NULL : toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(float value, Unit> unit) {
- return toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(int value, Unit> unit) {
- return toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(double value, Unit> unit) {
- return toQuantityType(new BigDecimal(value), unit);
- }
-
- public static State toQuantityType(@Nullable BigDecimal value, Unit> unit) {
- return value == null ? UnDefType.NULL : new QuantityType<>(value, unit);
- }
-
- public static State toRawType(String pictureUrl) {
- RawType picture = HttpUtil.downloadImage(pictureUrl);
- return picture == null ? UnDefType.UNDEF : picture;
- }
-}
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/NetatmoConstants.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/NetatmoConstants.java
index 03b1a1ff07606..c3c674243cea4 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/NetatmoConstants.java
+++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/NetatmoConstants.java
@@ -83,16 +83,6 @@ public enum MeasureClass {
public static final String NETATMO_BASE_URL = "https://api.netatmo.com/";
public static final String NETATMO_APP_URL = "https://app.netatmo.net/";
- // Units of measurement of the data delivered by the API
- // public static final Unit TEMPERATURE_UNIT = SIUnits.CELSIUS;
- // public static final Unit HUMIDITY_UNIT = Units.PERCENT;
- // public static final Unit PRESSURE_UNIT = HECTO(SIUnits.PASCAL);
- // public static final Unit WIND_SPEED_UNIT = SIUnits.KILOMETRE_PER_HOUR;
- // public static final Unit WIND_DIRECTION_UNIT = Units.DEGREE_ANGLE;
- // public static final Unit RAIN_UNIT = MILLI(SIUnits.METRE);
- // public static final Unit CO2_UNIT = Units.PARTS_PER_MILLION;
- // public static final Unit NOISE_UNIT = Units.DECIBEL;
-
public enum MeasureType {
SUM_RAIN,
@SerializedName("Temperature")
@@ -144,9 +134,6 @@ public String getDescriptor() {
}
// Default unit associated with each kind of measurement
- // public static final Map> MEASUREUNITS = Map.of(MeasureType.SUM_RAIN, RAIN_UNIT,
- // MeasureType.TEMP, TEMPERATURE_UNIT, MeasureType.HUM, HUMIDITY_UNIT, MeasureType.CO2, CO2_UNIT,
- // MeasureType.NOISE, NOISE_UNIT, MeasureType.PRESSURE, PRESSURE_UNIT, MeasureType.WIND, WIND_SPEED_UNIT);
public static final Map MEASUREUNITS = Map.of(MeasureType.SUM_RAIN,
MeasureClass.RAIN_QTTY, MeasureType.TEMP, MeasureClass.EXTERIOR_TEMPERATURE, MeasureType.HUM,
MeasureClass.HUMIDITY, MeasureType.CO2, MeasureClass.CO2, MeasureType.NOISE, MeasureClass.NOISE,
@@ -199,7 +186,7 @@ public static enum Scope {
// Radio signal quality thresholds
private static final int[] EMPTY_INT_ARRAY = new int[0];
- public static final int[] WIFI_SIGNAL_LEVELS = new int[] { 86, 71, 56 }; // Resp : bad, average, good
+ public static final int[] WIFI_SIGNAL_LEVELS = new int[] { 99, 84, 69, 54 }; // Resp : bad, average, good, full
public static final int[] RADIO_SIGNAL_LEVELS = new int[] { 90, 80, 70, 60 }; // Resp : low, medium, high, full
public static final int[] NO_RADIO = EMPTY_INT_ARRAY;
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/WeatherApi.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/WeatherApi.java
index 880491520685e..92ca5109d3855 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/WeatherApi.java
+++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/WeatherApi.java
@@ -81,14 +81,14 @@ public double getMeasurements(String deviceId, @Nullable String moduleId, Measur
MeasureLimit limit) throws NetatmoException {
List result = getmeasure(deviceId, moduleId, scale,
new String[] { (limit.toString() + "_" + type.toString()).toLowerCase() }, 0, 0, 0, false, false);
- return result.size() > 0 ? result.get(0).getSingleValue() : Double.NaN;
+ return !result.isEmpty() ? result.get(0).getSingleValue() : Double.NaN;
}
public double getMeasurements(String deviceId, @Nullable String moduleId, MeasureScale scale, MeasureType type)
throws NetatmoException {
List result = getmeasure(deviceId, moduleId, scale,
new String[] { type.toString().toLowerCase() }, 0, 0, 0, false, false);
- return result.size() > 0 ? result.get(0).getSingleValue() : Double.NaN;
+ return !result.isEmpty() ? result.get(0).getSingleValue() : Double.NaN;
}
public List getmeasure(String deviceId, @Nullable String moduleId, MeasureScale scale,
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAMeasureBodyElem.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAMeasureBodyElem.java
index b02c3ec5df225..a923b1961454b 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAMeasureBodyElem.java
+++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAMeasureBodyElem.java
@@ -41,9 +41,9 @@ public List> getValue() {
}
public Double getSingleValue() {
- if (value.size() > 0) {
+ if (!value.isEmpty()) {
List first = value.get(0);
- if (first.size() > 0) {
+ if (!first.isEmpty()) {
return first.get(0);
}
}
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/discovery/NetatmoModuleDiscoveryService.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/discovery/NetatmoModuleDiscoveryService.java
deleted file mode 100644
index 7454cb92ac540..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/discovery/NetatmoModuleDiscoveryService.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.netatmo.internal.discovery;
-
-import static org.openhab.binding.netatmo.internal.APIUtils.*;
-import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.netatmo.internal.handler.NetatmoBridgeHandler;
-import org.openhab.binding.netatmo.internal.handler.NetatmoDataListener;
-import org.openhab.core.config.discovery.AbstractDiscoveryService;
-import org.openhab.core.config.discovery.DiscoveryResult;
-import org.openhab.core.config.discovery.DiscoveryResultBuilder;
-import org.openhab.core.i18n.LocaleProvider;
-import org.openhab.core.i18n.TranslationProvider;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingTypeUID;
-import org.openhab.core.thing.ThingUID;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-
-import io.swagger.client.model.NAHealthyHomeCoach;
-import io.swagger.client.model.NAMain;
-import io.swagger.client.model.NAPlug;
-import io.swagger.client.model.NAStationModule;
-import io.swagger.client.model.NAWelcomeCamera;
-import io.swagger.client.model.NAWelcomeHome;
-
-/**
- * The {@link NetatmoModuleDiscoveryService} searches for available Netatmo
- * devices and modules connected to the API console
- *
- * @author Gaël L'hopital - Initial contribution
- * @author Ing. Peter Weiss - Welcome camera implementation
- *
- */
-@NonNullByDefault
-public class NetatmoModuleDiscoveryService extends AbstractDiscoveryService implements NetatmoDataListener {
- private static final int SEARCH_TIME = 5;
- private final NetatmoBridgeHandler netatmoBridgeHandler;
-
- public NetatmoModuleDiscoveryService(NetatmoBridgeHandler netatmoBridgeHandler, LocaleProvider localeProvider,
- TranslationProvider translationProvider) {
- super(SUPPORTED_DEVICE_THING_TYPES_UIDS, SEARCH_TIME);
- this.netatmoBridgeHandler = netatmoBridgeHandler;
- this.localeProvider = localeProvider;
- this.i18nProvider = translationProvider;
- }
-
- @Override
- public void activate(@Nullable Map configProperties) {
- super.activate(configProperties);
- netatmoBridgeHandler.registerDataListener(this);
- }
-
- @Override
- public void deactivate() {
- netatmoBridgeHandler.unregisterDataListener(this);
- super.deactivate();
- }
-
- @Override
- public void startScan() {
- if (netatmoBridgeHandler.configuration.readStation) {
- netatmoBridgeHandler.getStationsDataBody(null).ifPresent(dataBody -> {
- nonNullList(dataBody.getDevices()).forEach(station -> {
- discoverWeatherStation(station);
- });
- });
- }
- if (netatmoBridgeHandler.configuration.readHealthyHomeCoach) {
- netatmoBridgeHandler.getHomecoachDataBody(null).ifPresent(dataBody -> {
- nonNullList(dataBody.getDevices()).forEach(homecoach -> {
- discoverHomeCoach(homecoach);
- });
- });
- }
- if (netatmoBridgeHandler.configuration.readThermostat) {
- netatmoBridgeHandler.getThermostatsDataBody(null).ifPresent(dataBody -> {
- nonNullList(dataBody.getDevices()).forEach(plug -> {
- discoverThermostat(plug);
- });
- });
- }
- if (netatmoBridgeHandler.configuration.readWelcome || netatmoBridgeHandler.configuration.readPresence) {
- netatmoBridgeHandler.getWelcomeDataBody(null).ifPresent(dataBody -> {
- nonNullList(dataBody.getHomes()).forEach(home -> {
- discoverWelcomeHome(home);
- });
- });
- }
- }
-
- @Override
- protected synchronized void stopScan() {
- super.stopScan();
- removeOlderResults(getTimestampOfLastScan(), netatmoBridgeHandler.getThing().getUID());
- }
-
- @Override
- public void onDataRefreshed(Object data) {
- if (!isBackgroundDiscoveryEnabled()) {
- return;
- }
- if (data instanceof NAMain) {
- discoverWeatherStation((NAMain) data);
- } else if (data instanceof NAPlug) {
- discoverThermostat((NAPlug) data);
- } else if (data instanceof NAHealthyHomeCoach) {
- discoverHomeCoach((NAHealthyHomeCoach) data);
- } else if (data instanceof NAWelcomeHome) {
- discoverWelcomeHome((NAWelcomeHome) data);
- }
- }
-
- private void discoverThermostat(NAPlug plug) {
- onDeviceAddedInternal(plug.getId(), null, plug.getType(), plug.getStationName(), plug.getFirmware());
- nonNullList(plug.getModules()).forEach(thermostat -> {
- onDeviceAddedInternal(thermostat.getId(), plug.getId(), thermostat.getType(), thermostat.getModuleName(),
- thermostat.getFirmware());
- });
- }
-
- private void discoverHomeCoach(NAHealthyHomeCoach homecoach) {
- onDeviceAddedInternal(homecoach.getId(), null, homecoach.getType(), homecoach.getName(),
- homecoach.getFirmware());
- }
-
- private void discoverWeatherStation(NAMain station) {
- final boolean isFavorite = station.isFavorite() != null && station.isFavorite();
- final String weatherStationName = createWeatherStationName(station, isFavorite);
-
- onDeviceAddedInternal(station.getId(), null, station.getType(), weatherStationName, station.getFirmware());
- nonNullList(station.getModules()).forEach(module -> {
- onDeviceAddedInternal(module.getId(), station.getId(), module.getType(),
- createWeatherModuleName(station, module, isFavorite), module.getFirmware());
- });
- }
-
- private void discoverWelcomeHome(NAWelcomeHome home) {
- // I observed that Thermostat homes are also reported here by Netatmo API
- // So I ignore homes that have an empty list of cameras
- List cameras = nonNullList(home.getCameras());
- if (!cameras.isEmpty()) {
- onDeviceAddedInternal(home.getId(), null, WELCOME_HOME_THING_TYPE.getId(), home.getName(), null);
- // Discover Cameras
- cameras.forEach(camera -> {
- onDeviceAddedInternal(camera.getId(), home.getId(), camera.getType(), camera.getName(), null);
- });
-
- // Discover Known Persons
- nonNullStream(home.getPersons()).filter(person -> person.getPseudo() != null).forEach(person -> {
- onDeviceAddedInternal(person.getId(), home.getId(), WELCOME_PERSON_THING_TYPE.getId(),
- person.getPseudo(), null);
- });
- }
- }
-
- private void onDeviceAddedInternal(String id, @Nullable String parentId, String type, String name,
- @Nullable Integer firmwareVersion) {
- ThingUID thingUID = findThingUID(type, id);
- Map properties = new HashMap<>();
-
- properties.put(EQUIPMENT_ID, id);
- if (parentId != null) {
- properties.put(PARENT_ID, parentId);
- }
- if (firmwareVersion != null) {
- properties.put(Thing.PROPERTY_VENDOR, VENDOR);
- properties.put(Thing.PROPERTY_FIRMWARE_VERSION, firmwareVersion);
- properties.put(Thing.PROPERTY_MODEL_ID, type);
- properties.put(Thing.PROPERTY_SERIAL_NUMBER, id);
- }
- addDiscoveredThing(thingUID, properties, name);
- }
-
- private void addDiscoveredThing(ThingUID thingUID, Map properties, String displayLabel) {
- DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
- .withBridge(netatmoBridgeHandler.getThing().getUID()).withLabel(displayLabel)
- .withRepresentationProperty(EQUIPMENT_ID).build();
-
- thingDiscovered(discoveryResult);
- }
-
- private ThingUID findThingUID(String thingType, String thingId) throws IllegalArgumentException {
- for (ThingTypeUID supportedThingTypeUID : getSupportedThingTypes()) {
- String uid = supportedThingTypeUID.getId();
-
- if (uid.equalsIgnoreCase(thingType)) {
- return new ThingUID(supportedThingTypeUID, netatmoBridgeHandler.getThing().getUID(),
- thingId.replaceAll("[^a-zA-Z0-9_]", ""));
- }
- }
-
- throw new IllegalArgumentException("Unsupported device type discovered : " + thingType);
- }
-
- private String createWeatherStationName(NAMain station, boolean isFavorite) {
- StringBuilder nameBuilder = new StringBuilder();
- nameBuilder.append(localizeType(station.getType()));
- if (station.getStationName() != null) {
- nameBuilder.append(' ');
- nameBuilder.append(station.getStationName());
- }
- if (isFavorite) {
- nameBuilder.append(" (favorite)");
- }
- return nameBuilder.toString();
- }
-
- private String createWeatherModuleName(NAMain station, NAStationModule module, boolean isFavorite) {
- StringBuilder nameBuilder = new StringBuilder();
- if (module.getModuleName() != null) {
- nameBuilder.append(module.getModuleName());
- } else {
- nameBuilder.append(localizeType(module.getType()));
- }
- if (station.getStationName() != null) {
- nameBuilder.append(' ');
- nameBuilder.append(station.getStationName());
- }
- if (isFavorite) {
- nameBuilder.append(" (favorite)");
- }
- return nameBuilder.toString();
- }
-
- private String localizeType(String typeName) {
- Bundle bundle = FrameworkUtil.getBundle(this.getClass());
- @Nullable
- String localizedType = i18nProvider.getText(bundle, "thing-type.netatmo." + typeName + ".label", typeName,
- localeProvider.getLocale());
- if (localizedType != null) {
- return localizedType;
- }
- return typeName;
- }
-}
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/NetatmoBridgeHandler.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/NetatmoBridgeHandler.java
deleted file mode 100644
index 61ce9fa850f94..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/NetatmoBridgeHandler.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.netatmo.internal.handler;
-
-import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
-
-import org.apache.oltu.oauth2.client.OAuthClient;
-import org.apache.oltu.oauth2.client.URLConnectionClient;
-import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
-import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
-import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
-import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
-import org.apache.oltu.oauth2.common.message.types.GrantType;
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.netatmo.internal.config.NetatmoBridgeConfiguration;
-import org.openhab.binding.netatmo.internal.webhook.NAWebhookCameraEvent;
-import org.openhab.binding.netatmo.internal.webhook.NAWebhookCameraEventPerson;
-import org.openhab.binding.netatmo.internal.webhook.WelcomeWebHookServlet;
-import org.openhab.core.thing.Bridge;
-import org.openhab.core.thing.Channel;
-import org.openhab.core.thing.ChannelUID;
-import org.openhab.core.thing.Thing;
-import org.openhab.core.thing.ThingStatus;
-import org.openhab.core.thing.ThingStatusDetail;
-import org.openhab.core.thing.binding.BaseBridgeHandler;
-import org.openhab.core.types.Command;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.swagger.client.ApiClient;
-import io.swagger.client.ApiException;
-import io.swagger.client.api.HealthyhomecoachApi;
-import io.swagger.client.api.PartnerApi;
-import io.swagger.client.api.StationApi;
-import io.swagger.client.api.ThermostatApi;
-import io.swagger.client.api.WelcomeApi;
-import io.swagger.client.auth.Authentication;
-import io.swagger.client.auth.OAuth;
-import io.swagger.client.model.NAHealthyHomeCoachDataBody;
-import io.swagger.client.model.NAMeasureBodyElem;
-import io.swagger.client.model.NAStationDataBody;
-import io.swagger.client.model.NAThermostatDataBody;
-import io.swagger.client.model.NAWelcomeHomeData;
-
-/**
- * {@link NetatmoBridgeHandler} is the handler for a Netatmo API and connects it
- * to the framework. The devices and modules uses the
- * {@link NetatmoBridgeHandler} to request informations about their status
- *
- * @author Gaël L'hopital - Initial contribution OH2 version
- * @author Rob Nielsen - Added day, week, and month measurements to the weather station and modules
- *
- */
-@NonNullByDefault
-public class NetatmoBridgeHandler extends BaseBridgeHandler {
- private final Logger logger = LoggerFactory.getLogger(NetatmoBridgeHandler.class);
-
- public NetatmoBridgeConfiguration configuration = new NetatmoBridgeConfiguration();
- private @Nullable ScheduledFuture> refreshJob;
- private @Nullable APICreator apiCreator;
- private @Nullable WelcomeWebHookServlet webHookServlet;
- private List dataListeners = new CopyOnWriteArrayList<>();
-
- private static class APICreator {
-
- private final ApiClient apiClient;
- private final Map, Object> apiMap;
-
- private APICreator(ApiClient apiClient) {
- super();
- this.apiClient = apiClient;
- apiMap = new HashMap<>();
- }
-
- @SuppressWarnings("unchecked")
- public T getAPI(Class apiClass) {
- T api = (T) apiMap.get(apiClass);
- if (api == null) {
- try {
- api = apiClass.getDeclaredConstructor(ApiClient.class).newInstance(apiClient);
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException
- | NoSuchMethodException e) {
- throw new RuntimeException("Error on executing API class constructor!", e);
- }
- apiMap.put(apiClass, api);
- }
- return api;
- }
- }
-
- public NetatmoBridgeHandler(Bridge bridge, @Nullable WelcomeWebHookServlet webHookServlet) {
- super(bridge);
- this.webHookServlet = webHookServlet;
- }
-
- @Override
- public void initialize() {
- logger.debug("Initializing Netatmo API bridge handler.");
-
- configuration = getConfigAs(NetatmoBridgeConfiguration.class);
- scheduleTokenInitAndRefresh();
- }
-
- private void connectionSucceed() {
- updateStatus(ThingStatus.ONLINE);
- WelcomeWebHookServlet servlet = webHookServlet;
- String webHookURI = getWebHookURI();
- if (servlet != null && webHookURI != null) {
- getWelcomeApi().ifPresent(api -> {
- servlet.activate(this);
- logger.debug("Setting up Netatmo Welcome WebHook");
- api.addwebhook(webHookURI, WEBHOOK_APP);
- });
- }
- }
-
- private void scheduleTokenInitAndRefresh() {
- refreshJob = scheduler.scheduleWithFixedDelay(() -> {
- logger.debug("Initializing API Connection and scheduling token refresh every {}s",
- configuration.reconnectInterval);
- try {
- initializeApiClient();
- // I use a connection to Netatmo API using PartnerAPI to ensure that API is reachable
- getPartnerApi().partnerdevices();
- connectionSucceed();
- } catch (ApiException e) {
- switch (e.getCode()) {
- case 404: // If no partner station has been associated - likely to happen - we'll have this
- // error
- // but it means connection to API is OK
- connectionSucceed();
- break;
- case 403: // Forbidden Access maybe too many requests ? Let's wait next cycle
- logger.warn("Error 403 while connecting to Netatmo API, will retry in {} s",
- configuration.reconnectInterval);
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
- "Netatmo Access Forbidden, will retry in " + configuration.reconnectInterval
- + " seconds.");
- break;
- default:
- 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.CONFIGURATION_ERROR,
- "Unable to connect Netatmo API : " + e.getLocalizedMessage());
- }
- } catch (RuntimeException e) {
- if (logger.isDebugEnabled()) {
- logger.warn("Unable to connect Netatmo API : {}", e.getMessage(), e);
- } else {
- logger.warn("Unable to connect Netatmo API : {}", e.getMessage());
- }
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
- "Netatmo Access Failed, will retry in " + configuration.reconnectInterval + " seconds.");
- }
- // We'll do this every x seconds to guaranty token refresh
- }, 2, configuration.reconnectInterval, TimeUnit.SECONDS);
- }
-
- private void initializeApiClient() {
- try {
- ApiClient apiClient = new ApiClient();
-
- OAuthClientRequest oAuthRequest = OAuthClientRequest.tokenLocation("https://api.netatmo.net/oauth2/token")
- .setClientId(configuration.clientId).setClientSecret(configuration.clientSecret)
- .setUsername(configuration.username).setPassword(configuration.password).setScope(getApiScope())
- .setGrantType(GrantType.PASSWORD).buildBodyMessage();
-
- OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
-
- OAuthJSONAccessTokenResponse accessTokenResponse = oAuthClient.accessToken(oAuthRequest,
- OAuthJSONAccessTokenResponse.class);
- String accessToken = accessTokenResponse.getAccessToken();
-
- for (Authentication authentication : apiClient.getAuthentications().values()) {
- if (authentication instanceof OAuth) {
- ((OAuth) authentication).setAccessToken(accessToken);
- }
- }
-
- apiCreator = new APICreator(apiClient);
- } catch (OAuthSystemException | OAuthProblemException e) {
- throw new RuntimeException("Error on trying to get an access token!", e);
- }
- }
-
- private String getApiScope() {
- List scopes = new ArrayList<>();
-
- if (configuration.readStation) {
- scopes.add("read_station");
- }
-
- if (configuration.readThermostat) {
- scopes.add("read_thermostat");
- scopes.add("write_thermostat");
- }
-
- if (configuration.readHealthyHomeCoach) {
- scopes.add("read_homecoach");
- }
-
- if (configuration.readWelcome) {
- scopes.add("read_camera");
- scopes.add("access_camera");
- scopes.add("write_camera");
- }
-
- if (configuration.readPresence) {
- scopes.add("read_presence");
- scopes.add("access_presence");
- }
-
- return String.join(" ", scopes);
- }
-
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- logger.debug("Netatmo Bridge is read-only and does not handle commands");
- }
-
- public @Nullable PartnerApi getPartnerApi() {
- return apiCreator != null ? apiCreator.getAPI(PartnerApi.class) : null;
- }
-
- public Optional getStationApi() {
- return apiCreator != null ? Optional.of(apiCreator.getAPI(StationApi.class)) : Optional.empty();
- }
-
- public Optional getHomeCoachApi() {
- return apiCreator != null ? Optional.of(apiCreator.getAPI(HealthyhomecoachApi.class)) : Optional.empty();
- }
-
- public Optional getThermostatApi() {
- return apiCreator != null ? Optional.of(apiCreator.getAPI(ThermostatApi.class)) : Optional.empty();
- }
-
- public Optional getWelcomeApi() {
- return apiCreator != null ? Optional.of(apiCreator.getAPI(WelcomeApi.class)) : Optional.empty();
- }
-
- @Override
- public void dispose() {
- logger.debug("Running dispose()");
-
- WelcomeWebHookServlet servlet = webHookServlet;
- if (servlet != null && getWebHookURI() != null) {
- getWelcomeApi().ifPresent(api -> {
- logger.debug("Releasing Netatmo Welcome WebHook");
- servlet.deactivate();
- api.dropwebhook(WEBHOOK_APP);
- });
- }
-
- ScheduledFuture> job = refreshJob;
- if (job != null) {
- job.cancel(true);
- refreshJob = null;
- }
- }
-
- public Optional getStationsDataBody(@Nullable String equipmentId) {
- Optional data = getStationApi().map(api -> api.getstationsdata(equipmentId, true).getBody());
- updateStatus(ThingStatus.ONLINE);
- return data;
- }
-
- public List getStationMeasureResponses(String equipmentId, @Nullable String moduleId, String scale,
- List types) {
- List data = getStationApi()
- .map(api -> api.getmeasure(equipmentId, scale, types, moduleId, null, "last", 1, true, false).getBody())
- .orElse(null);
- updateStatus(ThingStatus.ONLINE);
- NAMeasureBodyElem element = data != null && !data.isEmpty() ? data.get(0) : null;
- return element != null ? element.getValue().get(0) : Collections.emptyList();
- }
-
- public Optional getHomecoachDataBody(@Nullable String equipmentId) {
- Optional data = getHomeCoachApi()
- .map(api -> api.gethomecoachsdata(equipmentId).getBody());
- updateStatus(ThingStatus.ONLINE);
- return data;
- }
-
- public Optional getThermostatsDataBody(@Nullable String equipmentId) {
- Optional data = getThermostatApi()
- .map(api -> api.getthermostatsdata(equipmentId).getBody());
- updateStatus(ThingStatus.ONLINE);
- return data;
- }
-
- public Optional getWelcomeDataBody(@Nullable String homeId) {
- Optional data = getWelcomeApi().map(api -> api.gethomedata(homeId, null).getBody());
- updateStatus(ThingStatus.ONLINE);
- return data;
- }
-
- /**
- * Returns the Url of the picture
- *
- * @return Url of the picture or UnDefType.UNDEF
- */
- public String getPictureUrl(@Nullable String id, @Nullable String key) {
- StringBuilder ret = new StringBuilder();
- if (id != null && key != null) {
- ret.append(WELCOME_PICTURE_URL).append("?").append(WELCOME_PICTURE_IMAGEID).append("=").append(id)
- .append("&").append(WELCOME_PICTURE_KEY).append("=").append(key);
- }
- return ret.toString();
- }
-
- public Optional findNAThing(@Nullable String searchedId) {
- List things = getThing().getThings();
- Stream naHandlers = things.stream().map(Thing::getHandler)
- .filter(AbstractNetatmoThingHandler.class::isInstance).map(AbstractNetatmoThingHandler.class::cast)
- .filter(handler -> handler.matchesId(searchedId));
- return naHandlers.findAny();
- }
-
- public void webHookEvent(NAWebhookCameraEvent event) {
- // This currently the only known event type but I suspect usage can grow in the future...
- if (event.getAppType() == NAWebhookCameraEvent.AppTypeEnum.CAMERA) {
- Set modules = new HashSet<>();
- if (WELCOME_EVENTS.contains(event.getEventType()) || PRESENCE_EVENTS.contains(event.getEventType())) {
- String cameraId = event.getCameraId();
- if (cameraId != null) {
- Optional camera = findNAThing(cameraId);
- camera.ifPresent(modules::add);
- }
- }
- if (HOME_EVENTS.contains(event.getEventType())) {
- String homeId = event.getHomeId();
- if (homeId != null) {
- Optional home = findNAThing(homeId);
- home.ifPresent(modules::add);
- }
- }
- if (PERSON_EVENTS.contains(event.getEventType())) {
- List persons = event.getPersons();
- persons.forEach(person -> {
- String personId = person.getId();
- if (personId != null) {
- Optional personHandler = findNAThing(personId);
- personHandler.ifPresent(modules::add);
- }
- });
- }
- modules.forEach(module -> {
- Channel channel = module.getThing().getChannel(CHANNEL_WELCOME_HOME_EVENT);
- if (channel != null) {
- triggerChannel(channel.getUID(), event.getEventType().toString());
- }
- });
- }
- }
-
- private @Nullable String getWebHookURI() {
- String webHookURI = null;
- WelcomeWebHookServlet webHookServlet = this.webHookServlet;
- if (configuration.webHookUrl != null && (configuration.readWelcome || configuration.readPresence)
- && webHookServlet != null) {
- webHookURI = configuration.webHookUrl + webHookServlet.getPath();
- }
- return webHookURI;
- }
-
- public boolean registerDataListener(NetatmoDataListener dataListener) {
- return dataListeners.add(dataListener);
- }
-
- public boolean unregisterDataListener(NetatmoDataListener dataListener) {
- return dataListeners.remove(dataListener);
- }
-
- public void checkForNewThings(Object data) {
- for (NetatmoDataListener dataListener : dataListeners) {
- dataListener.onDataRefreshed(data);
- }
- }
-}
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/PersonHandler.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/PersonHandler.java
index afeb85a17ffa4..080285cabf0f7 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/PersonHandler.java
+++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/PersonHandler.java
@@ -68,7 +68,7 @@ public void initialize() {
HomeSecurityHandler homeHandler = getHomeHandler();
if (homeHandler != null) {
List lastEvents = homeHandler.getLastEventOf(config.id);
- if (lastEvents.size() > 0) {
+ if (!lastEvents.isEmpty()) {
setEvent(lastEvents.get(0));
}
}
diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/webhook/NAWebhookEvent.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/webhook/NAWebhookEvent.java
index c12f2fe76903f..c472ed1427afd 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/webhook/NAWebhookEvent.java
+++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/webhook/NAWebhookEvent.java
@@ -59,7 +59,7 @@ public long getTime() {
@Override
public @Nullable String getPersonId() {
- if (persons.size() > 0) {
+ if (!persons.isEmpty()) {
return persons.keySet().iterator().next();
}
return null;
diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/binding/binding.xml b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/binding/binding.xml
index dbfc8d7a1f071..6a0f490e7f00f 100644
--- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/binding/binding.xml
+++ b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/binding/binding.xml
@@ -1,56 +1,52 @@
-
- Netatmo Binding
- The Netatmo binding integrates Weather Station with companion modules, Healthy Home Coach, Thermostat Plug
- and Welcome Camera.
-
-
-<<<<<<< Upstream, based on origin/main
-
-=======
-
-
- Client ID provided for the application you created on http://dev.netatmo.com/createapp
-
-
-
-
- Client Secret provided for the application you created
- password
-
-
-
-
- Your Netatmo API username (email)
-
-
-
-
- Your Netatmo API password
- password
-
-
-
-
- Protocol, public IP and port to access OH2 server from Internet.
-
-
-
-
- The reconnection interval to Netatmo API (in s).
- 5400
-
-
-
->>>>>>> 54453ef Rebase and spotless apply
-
- If set to true, the device and its associated modules are updated in the discovery inbox at each API
- call run to refresh device data. Default is false.
- false
-
-
+ xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
+
+ Netatmo Binding
+ The Netatmo binding integrates Weather Station with companion modules, Healthy Home Coach, Thermostat Plug
+ and Welcome Camera.
+
+
+
+
+ Client ID provided for the application you created on http://dev.netatmo.com/createapp
+
+
+
+
+ Client Secret provided for the application you created
+ password
+
+
+
+
+ Your Netatmo API username (email)
+
+
+
+
+ Your Netatmo API password
+ password
+
+
+
+
+ Protocol, public IP and port to access OH2 server from Internet.
+
+
+
+
+ The reconnection interval to Netatmo API (in s).
+ 5400
+
+
+
+
+ If set to true, the device and its associated modules are updated in the discovery inbox at each API
+ call run to refresh device data. Default is false.
+ false
+
+
diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/healthyhomecoach.xml b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/healthyhomecoach.xml
deleted file mode 100644
index 1d4a4ed0b0b7b..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/healthyhomecoach.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
- This represents the healthy home coach capable of reporting health
- index,temperature,humidity,pressure,air quality and sound level
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 99,84,69,54
- auto
-
-
- id
-
-
-
diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/station.xml b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/station.xml
deleted file mode 100644
index aa19c9ddcb429..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/station.xml
+++ /dev/null
@@ -1,295 +0,0 @@
-
-
-
-
-
-
-
-
-
- This represents the main indoor module capable of reporting temperature,humidity,pressure,air quality and
- sound level
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 99,84,69,54
- auto
-
-
- id
-
-
-
-
-
-
-
-
-
- This represents the outdoor module capable of reporting temperature and humidity
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 90,80,70,60
- 3600,4500,6000
-
-
- id
-
-
-
-
-
-
-
-
-
- This represents the wind module capable of reporting wind angle and strength
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 90,80,70,60
- 3950,4770,6000
-
-
- id
-
-
-
-
-
-
-
-
-
- This represents the Rain Gauge capable of measuring precipitation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 90,80,70,60
- 3600,4500,6000
-
-
- id
-
-
-
-
-
-
-
-
-
- This represents an additional indoor module capable of reporting temperature, humidity and CO2 level
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 90,80,70,60
- 4200,4920,6000
-
-
- id
-
-
-
-
diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/thermostat.xml b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/thermostat.xml
deleted file mode 100644
index b998b8738cde3..0000000000000
--- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/thermostat.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- This represents the thermostat relay
-
-
-
-
-
-
-
-
-
-
-
-
- 99,84,69,54
- 3600000
-
-
- id
-
-
-
-
-
-
-
-
-
- This represents the thermostat module itself
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 90,80,70,60
- 2700,3300,4500
-
-
- id
-
-
-
-