mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-26 15:21:41 +01:00
[melcloud] Improve null handling (#17295)
* Add null annotations Signed-off-by: Leo Siepel <leosiepel@gmail.com>
This commit is contained in:
parent
d5ad854aac
commit
600ca69c94
@ -17,6 +17,7 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.core.thing.ThingTypeUID;
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,6 +27,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||||||
* @author Luca Calcaterra - Initial contribution
|
* @author Luca Calcaterra - Initial contribution
|
||||||
* @author Wietse van Buitenen - Added heatpump device
|
* @author Wietse van Buitenen - Added heatpump device
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudBindingConstants {
|
public class MelCloudBindingConstants {
|
||||||
|
|
||||||
private static final String BINDING_ID = "melcloud";
|
private static final String BINDING_ID = "melcloud";
|
||||||
|
@ -14,6 +14,7 @@ package org.openhab.binding.melcloud.internal;
|
|||||||
|
|
||||||
import static org.openhab.binding.melcloud.internal.MelCloudBindingConstants.*;
|
import static org.openhab.binding.melcloud.internal.MelCloudBindingConstants.*;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.melcloud.internal.handler.MelCloudAccountHandler;
|
import org.openhab.binding.melcloud.internal.handler.MelCloudAccountHandler;
|
||||||
import org.openhab.binding.melcloud.internal.handler.MelCloudDeviceHandler;
|
import org.openhab.binding.melcloud.internal.handler.MelCloudDeviceHandler;
|
||||||
@ -33,6 +34,7 @@ import org.osgi.service.component.annotations.Component;
|
|||||||
* @author Luca Calcaterra - Initial contribution
|
* @author Luca Calcaterra - Initial contribution
|
||||||
* @author Wietse van Buitenen - Added heatpump device
|
* @author Wietse van Buitenen - Added heatpump device
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
@Component(configurationPid = "binding.melcloud", service = ThingHandlerFactory.class)
|
@Component(configurationPid = "binding.melcloud", service = ThingHandlerFactory.class)
|
||||||
public class MelCloudHandlerFactory extends BaseThingHandlerFactory {
|
public class MelCloudHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
@ -19,13 +19,15 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.openhab.binding.melcloud.internal.api.json.Device;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.DeviceStatus;
|
import org.openhab.binding.melcloud.internal.api.dto.Device;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.HeatpumpDeviceStatus;
|
import org.openhab.binding.melcloud.internal.api.dto.DeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.ListDevicesResponse;
|
import org.openhab.binding.melcloud.internal.api.dto.HeatpumpDeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.LoginClientResponse;
|
import org.openhab.binding.melcloud.internal.api.dto.ListDevicesResponse;
|
||||||
|
import org.openhab.binding.melcloud.internal.api.dto.LoginClientResponse;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
||||||
import org.openhab.core.io.net.http.HttpUtil;
|
import org.openhab.core.io.net.http.HttpUtil;
|
||||||
@ -45,6 +47,7 @@ import com.google.gson.JsonSyntaxException;
|
|||||||
* @author Pauli Anttila - Refactoring
|
* @author Pauli Anttila - Refactoring
|
||||||
* @author Wietse van Buitenen - Return all devices, added heatpump device
|
* @author Wietse van Buitenen - Return all devices, added heatpump device
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudConnection {
|
public class MelCloudConnection {
|
||||||
|
|
||||||
private static final String LOGIN_URL = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Login/ClientLogin";
|
private static final String LOGIN_URL = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Login/ClientLogin";
|
||||||
@ -54,18 +57,18 @@ public class MelCloudConnection {
|
|||||||
private static final int TIMEOUT_MILLISECONDS = 10000;
|
private static final int TIMEOUT_MILLISECONDS = 10000;
|
||||||
|
|
||||||
// Gson objects are safe to share across threads and are somewhat expensive to construct. Use a single instance.
|
// Gson objects are safe to share across threads and are somewhat expensive to construct. Use a single instance.
|
||||||
private static final Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
private static final Gson GSON = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||||
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
|
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(MelCloudConnection.class);
|
private final Logger logger = LoggerFactory.getLogger(MelCloudConnection.class);
|
||||||
|
|
||||||
private boolean isConnected = false;
|
private boolean isConnected = false;
|
||||||
private String sessionKey;
|
private String sessionKey = "";
|
||||||
|
|
||||||
public void login(String username, String password, int languageId)
|
public void login(String username, String password, int languageId)
|
||||||
throws MelCloudCommException, MelCloudLoginException {
|
throws MelCloudCommException, MelCloudLoginException {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
sessionKey = null;
|
sessionKey = "";
|
||||||
JsonObject jsonReq = new JsonObject();
|
JsonObject jsonReq = new JsonObject();
|
||||||
jsonReq.addProperty("Email", username);
|
jsonReq.addProperty("Email", username);
|
||||||
jsonReq.addProperty("Password", password);
|
jsonReq.addProperty("Password", password);
|
||||||
@ -79,7 +82,7 @@ public class MelCloudConnection {
|
|||||||
String loginResponse = HttpUtil.executeUrl("POST", LOGIN_URL, null, data, "application/json",
|
String loginResponse = HttpUtil.executeUrl("POST", LOGIN_URL, null, data, "application/json",
|
||||||
TIMEOUT_MILLISECONDS);
|
TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Login response: {}", loginResponse);
|
logger.debug("Login response: {}", loginResponse);
|
||||||
LoginClientResponse resp = gson.fromJson(loginResponse, LoginClientResponse.class);
|
LoginClientResponse resp = Objects.requireNonNull(GSON.fromJson(loginResponse, LoginClientResponse.class));
|
||||||
if (resp.getErrorId() != null) {
|
if (resp.getErrorId() != null) {
|
||||||
String errorMsg = String.format("Login failed, error code: %s", resp.getErrorId());
|
String errorMsg = String.format("Login failed, error code: %s", resp.getErrorId());
|
||||||
if (resp.getErrorMessage() != null) {
|
if (resp.getErrorMessage() != null) {
|
||||||
@ -101,7 +104,7 @@ public class MelCloudConnection {
|
|||||||
TIMEOUT_MILLISECONDS);
|
TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Device list response: {}", response);
|
logger.debug("Device list response: {}", response);
|
||||||
List<Device> devices = new ArrayList<>();
|
List<Device> devices = new ArrayList<>();
|
||||||
ListDevicesResponse[] buildings = gson.fromJson(response, ListDevicesResponse[].class);
|
ListDevicesResponse[] buildings = GSON.fromJson(response, ListDevicesResponse[].class);
|
||||||
Arrays.asList(buildings).forEach(building -> {
|
Arrays.asList(buildings).forEach(building -> {
|
||||||
if (building.getStructure().getDevices() != null) {
|
if (building.getStructure().getDevices() != null) {
|
||||||
devices.addAll(building.getStructure().getDevices());
|
devices.addAll(building.getStructure().getDevices());
|
||||||
@ -137,7 +140,7 @@ public class MelCloudConnection {
|
|||||||
try {
|
try {
|
||||||
String response = HttpUtil.executeUrl("GET", url, getHeaderProperties(), null, null, TIMEOUT_MILLISECONDS);
|
String response = HttpUtil.executeUrl("GET", url, getHeaderProperties(), null, null, TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Device status response: {}", response);
|
logger.debug("Device status response: {}", response);
|
||||||
return gson.fromJson(response, DeviceStatus.class);
|
return Objects.requireNonNull(GSON.fromJson(response, DeviceStatus.class));
|
||||||
} catch (IOException | JsonSyntaxException e) {
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
throw new MelCloudCommException("Error occurred during device status fetch", e);
|
throw new MelCloudCommException("Error occurred during device status fetch", e);
|
||||||
@ -146,14 +149,14 @@ public class MelCloudConnection {
|
|||||||
|
|
||||||
public DeviceStatus sendDeviceStatus(DeviceStatus deviceStatus) throws MelCloudCommException {
|
public DeviceStatus sendDeviceStatus(DeviceStatus deviceStatus) throws MelCloudCommException {
|
||||||
assertConnected();
|
assertConnected();
|
||||||
String content = gson.toJson(deviceStatus, DeviceStatus.class);
|
String content = GSON.toJson(deviceStatus, DeviceStatus.class);
|
||||||
logger.debug("Sending device status: {}", content);
|
logger.debug("Sending device status: {}", content);
|
||||||
InputStream data = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
InputStream data = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
||||||
try {
|
try {
|
||||||
String response = HttpUtil.executeUrl("POST", DEVICE_URL + "/SetAta", getHeaderProperties(), data,
|
String response = HttpUtil.executeUrl("POST", DEVICE_URL + "/SetAta", getHeaderProperties(), data,
|
||||||
"application/json", TIMEOUT_MILLISECONDS);
|
"application/json", TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Device status sending response: {}", response);
|
logger.debug("Device status sending response: {}", response);
|
||||||
return gson.fromJson(response, DeviceStatus.class);
|
return Objects.requireNonNull(GSON.fromJson(response, DeviceStatus.class));
|
||||||
} catch (IOException | JsonSyntaxException e) {
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
throw new MelCloudCommException("Error occurred during device command sending", e);
|
throw new MelCloudCommException("Error occurred during device command sending", e);
|
||||||
@ -166,7 +169,7 @@ public class MelCloudConnection {
|
|||||||
try {
|
try {
|
||||||
String response = HttpUtil.executeUrl("GET", url, getHeaderProperties(), null, null, TIMEOUT_MILLISECONDS);
|
String response = HttpUtil.executeUrl("GET", url, getHeaderProperties(), null, null, TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Device heatpump status response: {}", response);
|
logger.debug("Device heatpump status response: {}", response);
|
||||||
return gson.fromJson(response, HeatpumpDeviceStatus.class);
|
return Objects.requireNonNull(GSON.fromJson(response, HeatpumpDeviceStatus.class));
|
||||||
} catch (IOException | JsonSyntaxException e) {
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
throw new MelCloudCommException("Error occurred during heatpump device status fetch", e);
|
throw new MelCloudCommException("Error occurred during heatpump device status fetch", e);
|
||||||
@ -176,14 +179,14 @@ public class MelCloudConnection {
|
|||||||
public HeatpumpDeviceStatus sendHeatpumpDeviceStatus(HeatpumpDeviceStatus heatpumpDeviceStatus)
|
public HeatpumpDeviceStatus sendHeatpumpDeviceStatus(HeatpumpDeviceStatus heatpumpDeviceStatus)
|
||||||
throws MelCloudCommException {
|
throws MelCloudCommException {
|
||||||
assertConnected();
|
assertConnected();
|
||||||
String content = gson.toJson(heatpumpDeviceStatus, HeatpumpDeviceStatus.class);
|
String content = GSON.toJson(heatpumpDeviceStatus, HeatpumpDeviceStatus.class);
|
||||||
logger.debug("Sending heatpump device status: {}", content);
|
logger.debug("Sending heatpump device status: {}", content);
|
||||||
InputStream data = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
InputStream data = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
|
||||||
try {
|
try {
|
||||||
String response = HttpUtil.executeUrl("POST", DEVICE_URL + "/SetAtw", getHeaderProperties(), data,
|
String response = HttpUtil.executeUrl("POST", DEVICE_URL + "/SetAtw", getHeaderProperties(), data,
|
||||||
"application/json", TIMEOUT_MILLISECONDS);
|
"application/json", TIMEOUT_MILLISECONDS);
|
||||||
logger.debug("Device heatpump status sending response: {}", response);
|
logger.debug("Device heatpump status sending response: {}", response);
|
||||||
return gson.fromJson(response, HeatpumpDeviceStatus.class);
|
return Objects.requireNonNull(GSON.fromJson(response, HeatpumpDeviceStatus.class));
|
||||||
} catch (IOException | JsonSyntaxException e) {
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
throw new MelCloudCommException("Error occurred during heatpump device command sending", e);
|
throw new MelCloudCommException("Error occurred during heatpump device command sending", e);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.security.Permissions;
|
import java.security.Permissions;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.api.json;
|
package org.openhab.binding.melcloud.internal.api.dto;
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
@ -12,17 +12,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.config;
|
package org.openhab.binding.melcloud.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config class for an A.C. device.
|
* Config class for an A.C. device.
|
||||||
*
|
*
|
||||||
* @author Pauli Anttila - Initial Contribution
|
* @author Pauli Anttila - Initial Contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class AcDeviceConfig {
|
public class AcDeviceConfig {
|
||||||
|
|
||||||
public Integer deviceID;
|
public Integer deviceID = 0;
|
||||||
public Integer buildingID;
|
public @Nullable Integer buildingID;
|
||||||
public Integer pollingInterval;
|
public Integer pollingInterval = 360;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -12,17 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.config;
|
package org.openhab.binding.melcloud.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config class for MELCloud account parameters.
|
* Config class for MELCloud account parameters.
|
||||||
*
|
*
|
||||||
* @author Pauli Anttila - Initial Contribution
|
* @author Pauli Anttila - Initial Contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class AccountConfig {
|
public class AccountConfig {
|
||||||
|
|
||||||
public String username;
|
public String username = "";
|
||||||
public String password;
|
public String password = "";
|
||||||
public int language;
|
public int language = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -30,9 +33,6 @@ public class AccountConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getPasswordForPrinting() {
|
private String getPasswordForPrinting() {
|
||||||
if (password != null) {
|
return password.isEmpty() ? "<empty>" : "*********";
|
||||||
return password.isEmpty() ? "<empty>" : "*********";
|
|
||||||
}
|
|
||||||
return "<null>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.config;
|
package org.openhab.binding.melcloud.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config class for a Heatpump device.
|
* Config class for a Heatpump device.
|
||||||
*
|
*
|
||||||
* @author Wietse van Buitenen - Initial Contribution
|
* @author Wietse van Buitenen - Initial Contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class HeatpumpDeviceConfig {
|
public class HeatpumpDeviceConfig {
|
||||||
public Integer deviceID;
|
public Integer deviceID = 0;
|
||||||
public Integer buildingID;
|
public @Nullable Integer buildingID;
|
||||||
public Integer pollingInterval;
|
public Integer pollingInterval = 360;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -20,9 +20,10 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.openhab.binding.melcloud.internal.MelCloudBindingConstants;
|
import org.openhab.binding.melcloud.internal.MelCloudBindingConstants;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.Device;
|
import org.openhab.binding.melcloud.internal.api.dto.Device;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
||||||
import org.openhab.binding.melcloud.internal.handler.MelCloudAccountHandler;
|
import org.openhab.binding.melcloud.internal.handler.MelCloudAccountHandler;
|
||||||
@ -43,14 +44,15 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Pauli Anttila - Refactoring
|
* @author Pauli Anttila - Refactoring
|
||||||
* @author Wietse van Buitenen - Check device type, added heatpump device
|
* @author Wietse van Buitenen - Check device type, added heatpump device
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
@Component(scope = ServiceScope.PROTOTYPE, service = MelCloudDiscoveryService.class)
|
@Component(scope = ServiceScope.PROTOTYPE, service = MelCloudDiscoveryService.class)
|
||||||
public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryService<@NonNull MelCloudAccountHandler> {
|
public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryService<MelCloudAccountHandler> {
|
||||||
private final Logger logger = LoggerFactory.getLogger(MelCloudDiscoveryService.class);
|
private final Logger logger = LoggerFactory.getLogger(MelCloudDiscoveryService.class);
|
||||||
|
|
||||||
private static final String PROPERTY_DEVICE_ID = "deviceID";
|
private static final String PROPERTY_DEVICE_ID = "deviceID";
|
||||||
private static final int DISCOVER_TIMEOUT_SECONDS = 10;
|
private static final int DISCOVER_TIMEOUT_SECONDS = 10;
|
||||||
|
|
||||||
private ScheduledFuture<?> scanTask;
|
private @Nullable ScheduledFuture<?> scanTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a MelCloudDiscoveryService with enabled autostart.
|
* Creates a MelCloudDiscoveryService with enabled autostart.
|
||||||
@ -67,7 +69,8 @@ public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryServi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startScan() {
|
protected void startScan() {
|
||||||
if (this.scanTask != null) {
|
ScheduledFuture<?> scanTask = this.scanTask;
|
||||||
|
if (scanTask != null) {
|
||||||
scanTask.cancel(true);
|
scanTask.cancel(true);
|
||||||
}
|
}
|
||||||
this.scanTask = scheduler.schedule(() -> discoverDevices(), 0, TimeUnit.SECONDS);
|
this.scanTask = scheduler.schedule(() -> discoverDevices(), 0, TimeUnit.SECONDS);
|
||||||
@ -77,8 +80,9 @@ public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryServi
|
|||||||
protected void stopScan() {
|
protected void stopScan() {
|
||||||
super.stopScan();
|
super.stopScan();
|
||||||
|
|
||||||
if (this.scanTask != null) {
|
ScheduledFuture<?> scanTask = this.scanTask;
|
||||||
this.scanTask.cancel(true);
|
if (scanTask != null) {
|
||||||
|
scanTask.cancel(true);
|
||||||
this.scanTask = null;
|
this.scanTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +92,7 @@ public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryServi
|
|||||||
try {
|
try {
|
||||||
List<Device> deviceList = thingHandler.getDeviceList();
|
List<Device> deviceList = thingHandler.getDeviceList();
|
||||||
|
|
||||||
if (deviceList == null) {
|
if (deviceList.isEmpty()) {
|
||||||
logger.debug("No devices found");
|
logger.debug("No devices found");
|
||||||
} else {
|
} else {
|
||||||
ThingUID bridgeUID = thingHandler.getThing().getUID();
|
ThingUID bridgeUID = thingHandler.getThing().getUID();
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.exceptions;
|
package org.openhab.binding.melcloud.internal.exceptions;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception to encapsulate any issues communicating with MELCloud.
|
* Exception to encapsulate any issues communicating with MELCloud.
|
||||||
*
|
*
|
||||||
* @author Pauli Anttila - Initial Contribution
|
* @author Pauli Anttila - Initial Contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudCommException extends Exception {
|
public class MelCloudCommException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.melcloud.internal.exceptions;
|
package org.openhab.binding.melcloud.internal.exceptions;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception to encapsulate any login issues with MELCloud.
|
* Exception to encapsulate any login issues with MELCloud.
|
||||||
*
|
*
|
||||||
* @author Pauli Anttila - Initial Contribution
|
* @author Pauli Anttila - Initial Contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudLoginException extends Exception {
|
public class MelCloudLoginException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -15,15 +15,16 @@ package org.openhab.binding.melcloud.internal.handler;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.melcloud.internal.api.MelCloudConnection;
|
import org.openhab.binding.melcloud.internal.api.MelCloudConnection;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.Device;
|
import org.openhab.binding.melcloud.internal.api.dto.Device;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.DeviceStatus;
|
import org.openhab.binding.melcloud.internal.api.dto.DeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.api.json.HeatpumpDeviceStatus;
|
import org.openhab.binding.melcloud.internal.api.dto.HeatpumpDeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.config.AccountConfig;
|
import org.openhab.binding.melcloud.internal.config.AccountConfig;
|
||||||
import org.openhab.binding.melcloud.internal.discovery.MelCloudDiscoveryService;
|
import org.openhab.binding.melcloud.internal.discovery.MelCloudDiscoveryService;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
||||||
@ -47,14 +48,15 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Pauli Anttila - Refactoring
|
* @author Pauli Anttila - Refactoring
|
||||||
* @author Wietse van Buitenen - Return all devices, added heatpump device
|
* @author Wietse van Buitenen - Return all devices, added heatpump device
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudAccountHandler extends BaseBridgeHandler {
|
public class MelCloudAccountHandler extends BaseBridgeHandler {
|
||||||
private final Logger logger = LoggerFactory.getLogger(MelCloudAccountHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(MelCloudAccountHandler.class);
|
||||||
|
|
||||||
private MelCloudConnection connection;
|
private MelCloudConnection connection = new MelCloudConnection();
|
||||||
private List<Device> devices;
|
private List<Device> devices = Collections.emptyList();
|
||||||
private ScheduledFuture<?> connectionCheckTask;
|
private @Nullable ScheduledFuture<?> connectionCheckTask;
|
||||||
private AccountConfig config;
|
private AccountConfig config = new AccountConfig();
|
||||||
private boolean loginCredentialError;
|
private boolean loginCredentialError = false;
|
||||||
|
|
||||||
public MelCloudAccountHandler(Bridge bridge) {
|
public MelCloudAccountHandler(Bridge bridge) {
|
||||||
super(bridge);
|
super(bridge);
|
||||||
@ -69,8 +71,6 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
logger.debug("Initializing MELCloud account handler.");
|
logger.debug("Initializing MELCloud account handler.");
|
||||||
config = getConfigAs(AccountConfig.class);
|
config = getConfigAs(AccountConfig.class);
|
||||||
connection = new MelCloudConnection();
|
|
||||||
devices = Collections.emptyList();
|
|
||||||
loginCredentialError = false;
|
loginCredentialError = false;
|
||||||
startConnectionCheck();
|
startConnectionCheck();
|
||||||
}
|
}
|
||||||
@ -79,9 +79,7 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
public void dispose() {
|
public void dispose() {
|
||||||
logger.debug("Running dispose()");
|
logger.debug("Running dispose()");
|
||||||
stopConnectionCheck();
|
stopConnectionCheck();
|
||||||
connection = null;
|
|
||||||
devices = Collections.emptyList();
|
devices = Collections.emptyList();
|
||||||
config = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,6 +100,7 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
throw new MelCloudLoginException("Connection to MELCloud can't be opened because of wrong credentials");
|
throw new MelCloudLoginException("Connection to MELCloud can't be opened because of wrong credentials");
|
||||||
}
|
}
|
||||||
logger.debug("Initializing connection to MELCloud");
|
logger.debug("Initializing connection to MELCloud");
|
||||||
|
|
||||||
updateStatus(ThingStatus.OFFLINE);
|
updateStatus(ThingStatus.OFFLINE);
|
||||||
try {
|
try {
|
||||||
connection.login(config.username, config.password, config.language);
|
connection.login(config.username, config.password, config.language);
|
||||||
@ -139,10 +138,10 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceStatus fetchDeviceStatus(int deviceId, Optional<Integer> buildingId)
|
public DeviceStatus fetchDeviceStatus(int deviceId, @Nullable Integer buildingId)
|
||||||
throws MelCloudCommException, MelCloudLoginException {
|
throws MelCloudCommException, MelCloudLoginException {
|
||||||
connectIfNotConnected();
|
connectIfNotConnected();
|
||||||
int bid = buildingId.orElse(findBuildingId(deviceId));
|
int bid = buildingId != null ? buildingId : findBuildingId(deviceId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return connection.fetchDeviceStatus(deviceId, bid);
|
return connection.fetchDeviceStatus(deviceId, bid);
|
||||||
@ -165,10 +164,10 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HeatpumpDeviceStatus fetchHeatpumpDeviceStatus(int deviceId, Optional<Integer> buildingId)
|
public HeatpumpDeviceStatus fetchHeatpumpDeviceStatus(int deviceId, @Nullable Integer buildingId)
|
||||||
throws MelCloudCommException, MelCloudLoginException {
|
throws MelCloudCommException, MelCloudLoginException {
|
||||||
connectIfNotConnected();
|
connectIfNotConnected();
|
||||||
int bid = buildingId.orElse(findBuildingId(deviceId));
|
int bid = buildingId != null ? buildingId : findBuildingId(deviceId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return connection.fetchHeatpumpDeviceStatus(deviceId, bid);
|
return connection.fetchHeatpumpDeviceStatus(deviceId, bid);
|
||||||
@ -180,15 +179,13 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int findBuildingId(int deviceId) throws MelCloudCommException {
|
private int findBuildingId(int deviceId) throws MelCloudCommException {
|
||||||
if (devices != null) {
|
return devices.stream().filter(d -> d.getDeviceID() == deviceId).findFirst().orElseThrow(
|
||||||
return devices.stream().filter(d -> d.getDeviceID() == deviceId).findFirst().orElseThrow(
|
() -> new MelCloudCommException(String.format("Can't find building id for device id %s", deviceId)))
|
||||||
() -> new MelCloudCommException(String.format("Can't find building id for device id %s", deviceId)))
|
.getBuildingID();
|
||||||
.getBuildingID();
|
|
||||||
}
|
|
||||||
throw new MelCloudCommException(String.format("Can't find building id for device id %s", deviceId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startConnectionCheck() {
|
private void startConnectionCheck() {
|
||||||
|
ScheduledFuture<?> connectionCheckTask = this.connectionCheckTask;
|
||||||
if (connectionCheckTask == null || connectionCheckTask.isCancelled()) {
|
if (connectionCheckTask == null || connectionCheckTask.isCancelled()) {
|
||||||
logger.debug("Start periodic connection check");
|
logger.debug("Start periodic connection check");
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
@ -207,17 +204,18 @@ public class MelCloudAccountHandler extends BaseBridgeHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
connectionCheckTask = scheduler.scheduleWithFixedDelay(runnable, 0, 300, TimeUnit.SECONDS);
|
this.connectionCheckTask = scheduler.scheduleWithFixedDelay(runnable, 0, 300, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Connection check task already running");
|
logger.debug("Connection check task already running");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopConnectionCheck() {
|
private void stopConnectionCheck() {
|
||||||
|
ScheduledFuture<?> connectionCheckTask = this.connectionCheckTask;
|
||||||
if (connectionCheckTask != null) {
|
if (connectionCheckTask != null) {
|
||||||
logger.debug("Stop periodic connection check");
|
logger.debug("Stop periodic connection check");
|
||||||
connectionCheckTask.cancel(true);
|
connectionCheckTask.cancel(true);
|
||||||
connectionCheckTask = null;
|
this.connectionCheckTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,14 @@ import java.time.ZoneId;
|
|||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.measure.quantity.Temperature;
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
import org.openhab.binding.melcloud.internal.api.json.DeviceStatus;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.melcloud.internal.api.dto.DeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.config.AcDeviceConfig;
|
import org.openhab.binding.melcloud.internal.config.AcDeviceConfig;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
||||||
@ -46,6 +47,7 @@ import org.openhab.core.thing.ThingStatus;
|
|||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.ThingStatusInfo;
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.BridgeHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandler;
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.RefreshType;
|
import org.openhab.core.types.RefreshType;
|
||||||
@ -59,7 +61,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
* @author Luca Calcaterra - Initial contribution
|
* @author Luca Calcaterra - Initial contribution
|
||||||
* @author Pauli Anttila - Refactoring
|
* @author Pauli Anttila - Refactoring
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudDeviceHandler extends BaseThingHandler {
|
public class MelCloudDeviceHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private static final int EFFECTIVE_FLAG_POWER = 0x01;
|
private static final int EFFECTIVE_FLAG_POWER = 0x01;
|
||||||
@ -70,10 +72,10 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
private static final int EFFECTIVE_FLAG_VANE_HORIZONTAL = 0x100;
|
private static final int EFFECTIVE_FLAG_VANE_HORIZONTAL = 0x100;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(MelCloudDeviceHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(MelCloudDeviceHandler.class);
|
||||||
private AcDeviceConfig config;
|
private AcDeviceConfig config = new AcDeviceConfig();
|
||||||
private MelCloudAccountHandler melCloudHandler;
|
private @Nullable MelCloudAccountHandler melCloudHandler;
|
||||||
private DeviceStatus deviceStatus;
|
private @Nullable DeviceStatus deviceStatus;
|
||||||
private ScheduledFuture<?> refreshTask;
|
private @Nullable ScheduledFuture<?> refreshTask;
|
||||||
|
|
||||||
public MelCloudDeviceHandler(Thing thing) {
|
public MelCloudDeviceHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
@ -84,7 +86,7 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
logger.debug("Initializing {} handler.", getThing().getThingTypeUID());
|
logger.debug("Initializing {} handler.", getThing().getThingTypeUID());
|
||||||
|
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge == null) {
|
if (bridge == null || !(bridge.getHandler() instanceof BridgeHandler bridgeHandler)) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Bridge Not set");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Bridge Not set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -92,15 +94,16 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
config = getConfigAs(AcDeviceConfig.class);
|
config = getConfigAs(AcDeviceConfig.class);
|
||||||
logger.debug("A.C. device config: {}", config);
|
logger.debug("A.C. device config: {}", config);
|
||||||
|
|
||||||
initializeBridge(bridge.getHandler(), bridge.getStatus());
|
initializeBridge(bridgeHandler, bridge.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
logger.debug("Running dispose()");
|
logger.debug("Running dispose()");
|
||||||
|
ScheduledFuture<?> refreshTask = this.refreshTask;
|
||||||
if (refreshTask != null) {
|
if (refreshTask != null) {
|
||||||
refreshTask.cancel(true);
|
refreshTask.cancel(true);
|
||||||
refreshTask = null;
|
this.refreshTask = null;
|
||||||
}
|
}
|
||||||
melCloudHandler = null;
|
melCloudHandler = null;
|
||||||
}
|
}
|
||||||
@ -109,25 +112,21 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||||
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
|
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge != null) {
|
if (bridge != null && bridge.getHandler() instanceof BridgeHandler bridgeHandler) {
|
||||||
initializeBridge(bridge.getHandler(), bridgeStatusInfo.getStatus());
|
initializeBridge(bridgeHandler, bridgeStatusInfo.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeBridge(ThingHandler thingHandler, ThingStatus bridgeStatus) {
|
private void initializeBridge(ThingHandler thingHandler, ThingStatus bridgeStatus) {
|
||||||
logger.debug("initializeBridge {} for thing {}", bridgeStatus, getThing().getUID());
|
logger.debug("initializeBridge {} for thing {}", bridgeStatus, getThing().getUID());
|
||||||
|
|
||||||
if (thingHandler != null && bridgeStatus != null) {
|
melCloudHandler = (MelCloudAccountHandler) thingHandler;
|
||||||
melCloudHandler = (MelCloudAccountHandler) thingHandler;
|
|
||||||
|
|
||||||
if (bridgeStatus == ThingStatus.ONLINE) {
|
if (bridgeStatus == ThingStatus.ONLINE) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
startAutomaticRefresh();
|
startAutomaticRefresh();
|
||||||
} else {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
updateStatus(ThingStatus.OFFLINE);
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,12 +138,12 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
logger.debug("Refresh command not supported");
|
logger.debug("Refresh command not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
MelCloudAccountHandler melCloudHandler = this.melCloudHandler;
|
||||||
if (melCloudHandler == null) {
|
if (melCloudHandler == null) {
|
||||||
logger.warn("No connection to MELCloud available, ignoring command");
|
logger.warn("No connection to MELCloud available, ignoring command");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DeviceStatus deviceStatus = this.deviceStatus;
|
||||||
if (deviceStatus == null) {
|
if (deviceStatus == null) {
|
||||||
logger.info("No initial data available, bridge is probably offline. Ignoring command");
|
logger.info("No initial data available, bridge is probably offline. Ignoring command");
|
||||||
return;
|
return;
|
||||||
@ -229,18 +228,19 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startAutomaticRefresh() {
|
private void startAutomaticRefresh() {
|
||||||
|
ScheduledFuture<?> refreshTask = this.refreshTask;
|
||||||
if (refreshTask == null || refreshTask.isCancelled()) {
|
if (refreshTask == null || refreshTask.isCancelled()) {
|
||||||
refreshTask = scheduler.scheduleWithFixedDelay(this::getDeviceDataAndUpdateChannels, 1,
|
this.refreshTask = scheduler.scheduleWithFixedDelay(this::getDeviceDataAndUpdateChannels, 1,
|
||||||
config.pollingInterval, TimeUnit.SECONDS);
|
config.pollingInterval, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDeviceDataAndUpdateChannels() {
|
private void getDeviceDataAndUpdateChannels() {
|
||||||
if (melCloudHandler.isConnected()) {
|
MelCloudAccountHandler melCloudHandler = this.melCloudHandler;
|
||||||
|
if (melCloudHandler != null && melCloudHandler.isConnected()) {
|
||||||
logger.debug("Update device '{}' channels", getThing().getThingTypeUID());
|
logger.debug("Update device '{}' channels", getThing().getThingTypeUID());
|
||||||
try {
|
try {
|
||||||
DeviceStatus newDeviceStatus = melCloudHandler.fetchDeviceStatus(config.deviceID,
|
DeviceStatus newDeviceStatus = melCloudHandler.fetchDeviceStatus(config.deviceID, config.buildingID);
|
||||||
Optional.ofNullable(config.buildingID));
|
|
||||||
updateChannels(newDeviceStatus);
|
updateChannels(newDeviceStatus);
|
||||||
} catch (MelCloudLoginException e) {
|
} catch (MelCloudLoginException e) {
|
||||||
logger.debug("Login error occurred during device '{}' polling, reason {}. ",
|
logger.debug("Login error occurred during device '{}' polling, reason {}. ",
|
||||||
@ -255,7 +255,7 @@ public class MelCloudDeviceHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void updateChannels(DeviceStatus newDeviceStatus) {
|
private synchronized void updateChannels(DeviceStatus newDeviceStatus) {
|
||||||
deviceStatus = newDeviceStatus;
|
DeviceStatus deviceStatus = this.deviceStatus = newDeviceStatus;
|
||||||
for (Channel channel : getThing().getChannels()) {
|
for (Channel channel : getThing().getChannels()) {
|
||||||
updateChannels(channel.getUID().getId(), deviceStatus);
|
updateChannels(channel.getUID().getId(), deviceStatus);
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,14 @@ import java.time.ZoneId;
|
|||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.measure.quantity.Temperature;
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
import org.openhab.binding.melcloud.internal.api.json.HeatpumpDeviceStatus;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.melcloud.internal.api.dto.HeatpumpDeviceStatus;
|
||||||
import org.openhab.binding.melcloud.internal.config.HeatpumpDeviceConfig;
|
import org.openhab.binding.melcloud.internal.config.HeatpumpDeviceConfig;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
|
||||||
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
|
||||||
@ -45,6 +46,7 @@ import org.openhab.core.thing.ThingStatus;
|
|||||||
import org.openhab.core.thing.ThingStatusDetail;
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
import org.openhab.core.thing.ThingStatusInfo;
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||||
|
import org.openhab.core.thing.binding.BridgeHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandler;
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.RefreshType;
|
import org.openhab.core.types.RefreshType;
|
||||||
@ -57,16 +59,17 @@ import org.slf4j.LoggerFactory;
|
|||||||
*
|
*
|
||||||
* @author Wietse van Buitenen - Initial contribution
|
* @author Wietse van Buitenen - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
||||||
private static final long EFFECTIVE_FLAG_POWER = 1L;
|
private static final long EFFECTIVE_FLAG_POWER = 1L;
|
||||||
private static final long EFFECTIVE_FLAG_TEMPERATURE_ZONE1 = 8589934720L;
|
private static final long EFFECTIVE_FLAG_TEMPERATURE_ZONE1 = 8589934720L;
|
||||||
private static final long EFFECTIVE_FLAG_HOTWATER = 65536L;
|
private static final long EFFECTIVE_FLAG_HOTWATER = 65536L;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(MelCloudHeatpumpDeviceHandler.class);
|
private final Logger logger = LoggerFactory.getLogger(MelCloudHeatpumpDeviceHandler.class);
|
||||||
private HeatpumpDeviceConfig config;
|
private HeatpumpDeviceConfig config = new HeatpumpDeviceConfig();
|
||||||
private MelCloudAccountHandler melCloudHandler;
|
private @Nullable MelCloudAccountHandler melCloudHandler;
|
||||||
private HeatpumpDeviceStatus heatpumpDeviceStatus;
|
private @Nullable HeatpumpDeviceStatus heatpumpDeviceStatus;
|
||||||
private ScheduledFuture<?> refreshTask;
|
private @Nullable ScheduledFuture<?> refreshTask;
|
||||||
|
|
||||||
public MelCloudHeatpumpDeviceHandler(Thing thing) {
|
public MelCloudHeatpumpDeviceHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
@ -77,7 +80,7 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
logger.debug("Initializing {} handler.", getThing().getThingTypeUID());
|
logger.debug("Initializing {} handler.", getThing().getThingTypeUID());
|
||||||
|
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge == null) {
|
if (bridge == null || !(bridge.getHandler() instanceof BridgeHandler bridgeHandler)) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Bridge Not set");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Bridge Not set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -85,15 +88,16 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
config = getConfigAs(HeatpumpDeviceConfig.class);
|
config = getConfigAs(HeatpumpDeviceConfig.class);
|
||||||
logger.debug("Heatpump device config: {}", config);
|
logger.debug("Heatpump device config: {}", config);
|
||||||
|
|
||||||
initializeBridge(bridge.getHandler(), bridge.getStatus());
|
initializeBridge(bridgeHandler, bridge.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
logger.debug("Running dispose()");
|
logger.debug("Running dispose()");
|
||||||
|
ScheduledFuture<?> refreshTask = this.refreshTask;
|
||||||
if (refreshTask != null) {
|
if (refreshTask != null) {
|
||||||
refreshTask.cancel(true);
|
refreshTask.cancel(true);
|
||||||
refreshTask = null;
|
this.refreshTask = null;
|
||||||
}
|
}
|
||||||
melCloudHandler = null;
|
melCloudHandler = null;
|
||||||
}
|
}
|
||||||
@ -102,25 +106,21 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||||
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
|
logger.debug("bridgeStatusChanged {} for thing {}", bridgeStatusInfo, getThing().getUID());
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge != null) {
|
if (bridge != null && bridge.getHandler() instanceof BridgeHandler bridgeHandler) {
|
||||||
initializeBridge(bridge.getHandler(), bridgeStatusInfo.getStatus());
|
initializeBridge(bridgeHandler, bridgeStatusInfo.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeBridge(ThingHandler thingHandler, ThingStatus bridgeStatus) {
|
private void initializeBridge(ThingHandler thingHandler, ThingStatus bridgeStatus) {
|
||||||
logger.debug("initializeBridge {} for thing {}", bridgeStatus, getThing().getUID());
|
logger.debug("initializeBridge {} for thing {}", bridgeStatus, getThing().getUID());
|
||||||
|
|
||||||
if (thingHandler != null && bridgeStatus != null) {
|
melCloudHandler = (MelCloudAccountHandler) thingHandler;
|
||||||
melCloudHandler = (MelCloudAccountHandler) thingHandler;
|
|
||||||
|
|
||||||
if (bridgeStatus == ThingStatus.ONLINE) {
|
if (bridgeStatus == ThingStatus.ONLINE) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
startAutomaticRefresh();
|
startAutomaticRefresh();
|
||||||
} else {
|
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
updateStatus(ThingStatus.OFFLINE);
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,11 +133,12 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MelCloudAccountHandler melCloudHandler = this.melCloudHandler;
|
||||||
if (melCloudHandler == null) {
|
if (melCloudHandler == null) {
|
||||||
logger.warn("No connection to MELCloud available, ignoring command");
|
logger.warn("No connection to MELCloud available, ignoring command");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
HeatpumpDeviceStatus heatpumpDeviceStatus = this.heatpumpDeviceStatus;
|
||||||
if (heatpumpDeviceStatus == null) {
|
if (heatpumpDeviceStatus == null) {
|
||||||
logger.info("No initial data available, bridge is probably offline. Ignoring command");
|
logger.info("No initial data available, bridge is probably offline. Ignoring command");
|
||||||
return;
|
return;
|
||||||
@ -207,18 +208,20 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startAutomaticRefresh() {
|
private void startAutomaticRefresh() {
|
||||||
|
ScheduledFuture<?> refreshTask = this.refreshTask;
|
||||||
if (refreshTask == null || refreshTask.isCancelled()) {
|
if (refreshTask == null || refreshTask.isCancelled()) {
|
||||||
refreshTask = scheduler.scheduleWithFixedDelay(this::getDeviceDataAndUpdateChannels, 1,
|
this.refreshTask = scheduler.scheduleWithFixedDelay(this::getDeviceDataAndUpdateChannels, 1,
|
||||||
config.pollingInterval, TimeUnit.SECONDS);
|
config.pollingInterval, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDeviceDataAndUpdateChannels() {
|
private void getDeviceDataAndUpdateChannels() {
|
||||||
if (melCloudHandler.isConnected()) {
|
MelCloudAccountHandler melCloudHandler = this.melCloudHandler;
|
||||||
|
if (melCloudHandler != null && melCloudHandler.isConnected()) {
|
||||||
logger.debug("Update device '{}' channels", getThing().getThingTypeUID());
|
logger.debug("Update device '{}' channels", getThing().getThingTypeUID());
|
||||||
try {
|
try {
|
||||||
HeatpumpDeviceStatus newHeatpumpDeviceStatus = melCloudHandler
|
HeatpumpDeviceStatus newHeatpumpDeviceStatus = melCloudHandler
|
||||||
.fetchHeatpumpDeviceStatus(config.deviceID, Optional.ofNullable(config.buildingID));
|
.fetchHeatpumpDeviceStatus(config.deviceID, config.buildingID);
|
||||||
updateChannels(newHeatpumpDeviceStatus);
|
updateChannels(newHeatpumpDeviceStatus);
|
||||||
} catch (MelCloudLoginException e) {
|
} catch (MelCloudLoginException e) {
|
||||||
logger.debug("Login error occurred during device '{}' polling, reason {}. ",
|
logger.debug("Login error occurred during device '{}' polling, reason {}. ",
|
||||||
@ -233,7 +236,7 @@ public class MelCloudHeatpumpDeviceHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void updateChannels(HeatpumpDeviceStatus newHeatpumpDeviceStatus) {
|
private synchronized void updateChannels(HeatpumpDeviceStatus newHeatpumpDeviceStatus) {
|
||||||
heatpumpDeviceStatus = newHeatpumpDeviceStatus;
|
HeatpumpDeviceStatus heatpumpDeviceStatus = this.heatpumpDeviceStatus = newHeatpumpDeviceStatus;
|
||||||
for (Channel channel : getThing().getChannels()) {
|
for (Channel channel : getThing().getChannels()) {
|
||||||
updateChannels(channel.getUID().getId(), heatpumpDeviceStatus);
|
updateChannels(channel.getUID().getId(), heatpumpDeviceStatus);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user