From beade55ca6c3fa808d02a5a5532a902560303906 Mon Sep 17 00:00:00 2001 From: Markus Michels Date: Mon, 13 Nov 2023 19:37:04 +0100 Subject: [PATCH] [shelly] Fix resource leak, BLU script installation, TRV init, NPE on IPv6 mDNS discovery (#15798) * Fix resource leak when discovery handling failed and NPE when a IPv6 address is reported. * remove callApi(request/innerRequest from Shelly1HttpApi, which changes to callApi/httpRequest in ShellyHttpCLient. Signed-off-by: Markus Michels --- .../internal/ShellyBindingConstants.java | 2 +- .../internal/api/ShellyDeviceProfile.java | 11 ++- .../shelly/internal/api/ShellyHttpClient.java | 7 +- .../internal/api1/Shelly1CoIoTVersion2.java | 3 + .../internal/api1/Shelly1CoapHandler.java | 2 +- .../shelly/internal/api1/Shelly1HttpApi.java | 97 +------------------ .../shelly/internal/api2/Shelly2ApiRpc.java | 14 +-- .../discovery/ShellyDiscoveryParticipant.java | 18 ++-- .../internal/handler/ShellyBaseHandler.java | 26 +++-- .../internal/handler/ShellyComponents.java | 5 +- .../provider/ShellyChannelDefinitions.java | 4 +- .../main/resources/OH-INF/config/config2.xml | 4 - .../resources/OH-INF/config/configblu.xml | 2 +- .../resources/OH-INF/i18n/shelly.properties | 6 +- .../main/resources/sniplets/ov_device.html | 2 +- 15 files changed, 71 insertions(+), 132 deletions(-) diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java index e3300b776..3f3f23524 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyBindingConstants.java @@ -333,7 +333,7 @@ public class ShellyBindingConstants { public static final int UPDATE_MIN_DELAY = 15;// update every x triggers or when a key was pressed public static final int UPDATE_SETTINGS_INTERVAL_SECONDS = 60; // check for updates every x sec public static final int HEALTH_CHECK_INTERVAL_SEC = 300; // Health check interval, 5min - public static final int VIBRATION_FILTER_SEC = 5; // Absore duplicate vibration events for xx sec + public static final int VIBRATION_FILTER_SEC = 5; // Absorb duplicate vibration events for xx sec public static final String BUNDLE_RESOURCE_SNIPLETS = "sniplets"; // where to find code sniplets in the bundle public static final String BUNDLE_RESOURCE_SCRIPTS = "scripts"; // where to find scrips in the bundle diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java index 7e8f335b2..814917e26 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyDeviceProfile.java @@ -196,7 +196,8 @@ public class ShellyDeviceProfile { return; } - isBlu = thingType.startsWith("shellyblu"); // e.g. SBBT for BU Button + isGen2 = isGeneration2(thingType); + isBlu = isBluSeries(thingType); // e.g. SBBT for BLU Button isDimmer = deviceType.equalsIgnoreCase(SHELLYDT_DIMMER) || deviceType.equalsIgnoreCase(SHELLYDT_DIMMER2) || deviceType.equalsIgnoreCase(SHELLYDT_PLUSDIMMERUS) @@ -397,6 +398,14 @@ public class ShellyDeviceProfile { return ""; } + public static boolean isGeneration2(String thingType) { + return thingType.startsWith("shellyplus") || thingType.startsWith("shellypro") || isBluSeries(thingType); + } + + public static boolean isBluSeries(String thingType) { + return thingType.startsWith("shellyblu"); + } + public boolean coiotEnabled() { if ((settings.coiot != null) && (settings.coiot.enabled != null)) { return settings.coiot.enabled; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java index e82dc8bee..5b04bc58a 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpClient.java @@ -113,6 +113,8 @@ public class ShellyHttpClient { while (retries > 0) { try { apiResult = innerRequest(HttpMethod.GET, uri, null, ""); + + // If call doesn't throw an exception the device is reachable == no timeout if (timeout) { logger.debug("{}: API timeout #{}/{} recovered ({})", thingName, timeoutErrors, timeoutsRecovered, apiResult.getUrl()); @@ -128,9 +130,10 @@ public class ShellyHttpClient { } timeout = true; - retries--; timeoutErrors++; // count the retries logger.debug("{}: API Timeout, retry #{} ({})", thingName, timeoutErrors, e.toString()); + + retries--; } } throw new ShellyApiException("API Timeout or inconsistent result"); // successful @@ -174,7 +177,7 @@ public class ShellyHttpClient { } } fillPostData(request, data); - logger.trace("{}: HTTP {} for {} {}\n{}", thingName, method, url, data, request.getHeaders()); + logger.trace("{}: HTTP {} {}\n{}\n{}", thingName, method, url, request.getHeaders(), data); // Do request and get response ContentResponse contentResponse = request.send(); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java index 24f2b7147..5a599811f 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoIoTVersion2.java @@ -126,6 +126,9 @@ public class Shelly1CoIoTVersion2 extends Shelly1CoIoTProtocol implements Shelly thingHandler.requestUpdates(1, false); } break; + case "3122": // boost mode, Type=S, Range=0/1 + updateChannel(updates, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_BCONTROL, getOnOff(value > 0)); + break; default: processed = false; } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java index b3b88d71f..23c9cdede 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1CoapHandler.java @@ -182,7 +182,7 @@ public class Shelly1CoapHandler implements Shelly1CoapListener { for (Option opt : options) { if (opt.getNumber() == COIOT_OPTION_GLOBAL_DEVID) { String devid = opt.getStringValue(); - if (devid.contains("#")) { + if (devid.contains("#") && profile.mac != null) { // Format: ## String macid = substringBetween(devid, "#", "#"); if (profile.mac.toUpperCase().contains(macid.toUpperCase())) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java index 97d83ad7e..69a4d7bd5 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api1/Shelly1HttpApi.java @@ -20,20 +20,11 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpStatus; import org.openhab.binding.shelly.internal.api.ShellyApiException; import org.openhab.binding.shelly.internal.api.ShellyApiInterface; -import org.openhab.binding.shelly.internal.api.ShellyApiResult; import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile; import org.openhab.binding.shelly.internal.api.ShellyHttpClient; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyOtaCheckResult; @@ -258,7 +249,7 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa @Override public void setValveTemperature(int valveId, int value) throws ShellyApiException { - request("/thermostat/" + valveId + "?target_t_enabled=1&target_t=" + value); + httpRequest("/thermostat/" + valveId + "?target_t_enabled=1&target_t=" + value); } @Override @@ -273,17 +264,17 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa @Override public void setValveProfile(int valveId, int value) throws ShellyApiException { String uri = "/settings/thermostat/" + valveId + "?"; - request(uri + (value == 0 ? "schedule=0" : "schedule=1&schedule_profile=" + value)); + httpRequest(uri + (value == 0 ? "schedule=0" : "schedule=1&schedule_profile=" + value)); } @Override public void setValvePosition(int valveId, double value) throws ShellyApiException { - request("/thermostat/" + valveId + "?pos=" + value); // percentage to open the valve + httpRequest("/thermostat/" + valveId + "?pos=" + value); // percentage to open the valve } @Override public void setValveBoostTime(int valveId, int value) throws ShellyApiException { - request("/settings/thermostat/" + valveId + "?boost_minutes=" + value); + httpRequest("/settings/thermostat/" + valveId + "?boost_minutes=" + value); } @Override @@ -641,86 +632,6 @@ public class Shelly1HttpApi extends ShellyHttpClient implements ShellyApiInterfa return eventType + SHELLY_EVENTURL_SUFFIX; } - /** - * Submit GET request and return response, check for invalid responses - * - * @param uri: URI (e.g. "/settings") - */ - @Override - public T callApi(String uri, Class classOfT) throws ShellyApiException { - String json = request(uri); - return fromJson(gson, json, classOfT); - } - - private String request(String uri) throws ShellyApiException { - ShellyApiResult apiResult = new ShellyApiResult(); - int retries = 3; - boolean timeout = false; - while (retries > 0) { - try { - apiResult = innerRequest(HttpMethod.GET, uri); - if (timeout) { - logger.debug("{}: API timeout #{}/{} recovered ({})", thingName, timeoutErrors, timeoutsRecovered, - apiResult.getUrl()); - timeoutsRecovered++; - } - return apiResult.response; // successful - } catch (ShellyApiException e) { - if ((!e.isTimeout() && !apiResult.isHttpServerError()) || profile.hasBattery || (retries == 0)) { - // Sensor in sleep mode or API exception for non-battery device or retry counter expired - throw e; // non-timeout exception - } - - timeout = true; - retries--; - timeoutErrors++; // count the retries - logger.debug("{}: API Timeout, retry #{} ({})", thingName, timeoutErrors, e.toString()); - } - } - throw new ShellyApiException("API Timeout or inconsistent result"); // successful - } - - private ShellyApiResult innerRequest(HttpMethod method, String uri) throws ShellyApiException { - Request request = null; - String url = "http://" + config.deviceIp + uri; - ShellyApiResult apiResult = new ShellyApiResult(method.toString(), url); - - try { - request = httpClient.newRequest(url).method(method.toString()).timeout(SHELLY_API_TIMEOUT_MS, - TimeUnit.MILLISECONDS); - - if (!config.userId.isEmpty()) { - String value = config.userId + ":" + config.password; - request.header(HTTP_HEADER_AUTH, - HTTP_AUTH_TYPE_BASIC + " " + Base64.getEncoder().encodeToString(value.getBytes())); - } - request.header(HttpHeader.ACCEPT, CONTENT_TYPE_JSON); - logger.trace("{}: HTTP {} for {}", thingName, method, url); - - // Do request and get response - ContentResponse contentResponse = request.send(); - apiResult = new ShellyApiResult(contentResponse); - String response = contentResponse.getContentAsString().replace("\t", "").replace("\r\n", "").trim(); - logger.trace("{}: HTTP Response {}: {}", thingName, contentResponse.getStatus(), response); - - // validate response, API errors are reported as Json - if (contentResponse.getStatus() != HttpStatus.OK_200) { - throw new ShellyApiException(apiResult); - } - if (response.isEmpty() || !response.startsWith("{") && !response.startsWith("[") && !url.contains("/debug/") - && !url.contains("/sta_cache_reset")) { - throw new ShellyApiException("Unexpected response: " + response); - } - } catch (ExecutionException | InterruptedException | TimeoutException | IllegalArgumentException e) { - ShellyApiException ex = new ShellyApiException(apiResult, e); - if (!ex.isTimeout()) { // will be handled by the caller - logger.trace("{}: API call returned exception", thingName, ex); - } - throw ex; - } - return apiResult; - } - @Override public String getControlUriPrefix(Integer id) { String uri = ""; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiRpc.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiRpc.java index c1a9b67f8..d35273bcc 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiRpc.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiRpc.java @@ -319,14 +319,16 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac asyncApiRequest(SHELLYRPC_METHOD_GETSTATUS); // request periodic status updates from device try { - if (config.enableBluGateway != null) { + if (profile.alwaysOn && config.enableBluGateway != null) { logger.debug("{}: BLU Gateway support is {} for this device", thingName, config.enableBluGateway ? "enabled" : "disabled"); - boolean bluetooth = getBool(profile.settings.bluetooth); - if (config.enableBluGateway && !bluetooth) { - logger.info("{}: Bluetooth needs to be enabled to activate BLU Gateway mode", thingName); + if (config.enableBluGateway) { + boolean bluetooth = getBool(profile.settings.bluetooth); + if (config.enableBluGateway && !bluetooth) { + logger.info("{}: Bluetooth needs to be enabled to activate BLU Gateway mode", thingName); + } + installScript(SHELLY2_BLU_GWSCRIPT, config.enableBluGateway && bluetooth); } - installScript(SHELLY2_BLU_GWSCRIPT, config.enableBluGateway && bluetooth); } } catch (ShellyApiException e) { logger.debug("{}: Device config failed", thingName, e); @@ -1023,7 +1025,7 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac Shelly2RpcRequestParams params = new Shelly2RpcRequestParams(); if (prod || beta) { - params.stage = prod || beta ? "stable" : "beta"; + params.stage = prod ? "stable" : "beta"; } else { params.url = fwurl; } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java index 863c2b99a..967a65864 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/discovery/ShellyDiscoveryParticipant.java @@ -13,10 +13,11 @@ package org.openhab.binding.shelly.internal.discovery; import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*; -import static org.openhab.binding.shelly.internal.util.ShellyUtils.substringBeforeLast; +import static org.openhab.binding.shelly.internal.util.ShellyUtils.*; import static org.openhab.core.thing.Thing.PROPERTY_MODEL_ID; import java.io.IOException; +import java.net.Inet4Address; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -117,9 +118,9 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant { Map properties = new TreeMap<>(); name = service.getName().toLowerCase(); - String[] hostAddresses = service.getHostAddresses(); + Inet4Address[] hostAddresses = service.getInet4Addresses(); if ((hostAddresses != null) && (hostAddresses.length > 0)) { - address = hostAddresses[0]; + address = substringAfter(hostAddresses[0].toString(), "/"); } if (address.isEmpty()) { logger.trace("{}: Shelly device discovered with empty IP address (service-name={})", name, service); @@ -142,12 +143,11 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant { config.password = bindingConfig.defaultPassword; boolean gen2 = "2".equals(service.getPropertyString("gen")); + ShellyApiInterface api = null; try { - ShellyApiInterface api = gen2 ? new Shelly2ApiRpc(name, config, httpClient) - : new Shelly1HttpApi(name, config, httpClient); + api = gen2 ? new Shelly2ApiRpc(name, config, httpClient) : new Shelly1HttpApi(name, config, httpClient); api.initialize(); profile = api.getDeviceProfile(thingType); - api.close(); logger.debug("{}: Shelly settings : {}", name, profile.settingsJson); deviceName = profile.name; model = profile.deviceType; @@ -170,6 +170,10 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant { } } catch (IllegalArgumentException e) { // maybe some format description was buggy logger.debug("{}: Discovery failed!", name, e); + } finally { + if (api != null) { + api.close(); + } } if (thingUID != null) { @@ -185,7 +189,7 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant { String thingLabel = deviceName.isEmpty() ? name + " - " + address : deviceName + " (" + name + "@" + address + ")"; return DiscoveryResultBuilder.create(thingUID).withProperties(properties).withLabel(thingLabel) - .withRepresentationProperty(PROPERTY_DEV_NAME).build(); + .withRepresentationProperty(PROPERTY_SERVICE_NAME).build(); } } catch (IOException | NullPointerException e) { // maybe some format description was buggy diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java index 54cd538c1..c76a181e4 100755 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBaseHandler.java @@ -150,11 +150,8 @@ public abstract class ShellyBaseHandler extends BaseThingHandler Map properties = thing.getProperties(); String gen = getString(properties.get(PROPERTY_DEV_GEN)); String thingType = getThingType(); - if (gen.isEmpty() && thingType.startsWith("shellyplus") || thingType.startsWith("shellypro")) { - gen = "2"; - } - gen2 = "2".equals(gen); - blu = thingType.startsWith("shellyblu"); + gen2 = "2".equals(gen) || ShellyDeviceProfile.isGeneration2(thingType); + blu = ShellyDeviceProfile.isBluSeries(thingType); this.api = !blu ? !gen2 ? new Shelly1HttpApi(thingName, this) : new Shelly2ApiRpc(thingName, thingTable, this) : new ShellyBluApi(thingName, thingTable, this); if (gen2) { @@ -569,7 +566,9 @@ public abstract class ShellyBaseHandler extends BaseThingHandler status = "offline.conf-error-access-denied"; } else if (isWatchdogStarted()) { if (!isWatchdogExpired()) { - logger.debug("{}: Ignore API Timeout on {} {}, retry later", thingName, res.method, res.url); + if (profile.alwaysOn) { // suppress for battery powered sensors + logger.debug("{}: Ignore API Timeout on {} {}, retry later", thingName, res.method, res.url); + } } else { if (isThingOnline()) { status = "offline.status-error-watchdog"; @@ -799,7 +798,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler private boolean checkRestarted(ShellySettingsStatus status) { if (profile.isInitialized() && profile.alwaysOn /* exclude battery powered devices */ && (status.uptime != null && status.uptime < stats.lastUptime - || (!profile.status.update.oldVersion.isEmpty() + || (profile.status.update != null && !getString(profile.status.update.oldVersion).isEmpty() && !status.update.oldVersion.equals(profile.status.update.oldVersion)))) { logger.debug("{}: Device has been restarted, uptime={}/{}, firmware={}/{}", thingName, stats.lastUptime, getLong(status.uptime), profile.status.update.oldVersion, status.update.oldVersion); @@ -1022,10 +1021,14 @@ public abstract class ShellyBaseHandler extends BaseThingHandler config.serviceName = getString(properties.get(PROPERTY_SERVICE_NAME)); config.localIp = bindingConfig.localIP; config.localPort = String.valueOf(bindingConfig.httpPort); - if (config.userId.isEmpty() && !bindingConfig.defaultUserId.isEmpty()) { + if (!profile.isGen2 && config.userId.isEmpty() && !bindingConfig.defaultUserId.isEmpty()) { + // Gen2 has hard coded user "admin" config.userId = bindingConfig.defaultUserId; + logger.debug("{}: Using default userId {} from binding config", thingName, config.userId); + } + if (config.password.isEmpty() && !bindingConfig.defaultPassword.isEmpty()) { config.password = bindingConfig.defaultPassword; - logger.debug("{}: Using userId {} from bindingConfig", thingName, config.userId); + logger.debug("{}: Using default password from bindingConfig (userId={})", thingName, config.userId); } if (config.updateInterval == 0) { config.updateInterval = UPDATE_STATUS_INTERVAL_SECONDS * UPDATE_SKIP_COUNT; @@ -1052,6 +1055,11 @@ public abstract class ShellyBaseHandler extends BaseThingHandler private void checkVersion(ShellyDeviceProfile prf, ShellySettingsStatus status) { try { + if (prf.fwVersion.isEmpty()) { + // no fw version available (e.g. BLU device) + return; + } + ShellyVersionDTO version = new ShellyVersionDTO(); if (version.checkBeta(getString(prf.fwVersion))) { logger.info("{}: {}", prf.hostname, messages.get("versioncheck.beta", prf.fwVersion, prf.fwDate)); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java index 28569c9c0..cbac83ffc 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyComponents.java @@ -435,7 +435,10 @@ public class ShellyComponents { if (t.tmp != null) { updated |= updateTempChannel(thingHandler, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TEMP, t.tmp.value, t.tmp.units); - updated |= updateTempChannel(thingHandler, CHANNEL_GROUP_SENSOR, CHANNEL_CONTROL_SETTEMP, + if (t.targetTemp.unit == null) { + t.targetTemp.unit = t.tmp.units; + } + updated |= updateTempChannel(thingHandler, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SETTEMP, t.targetTemp.value, t.targetTemp.unit); } if (t.pos != null) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java index a83c3b5b7..4bb96355f 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/provider/ShellyChannelDefinitions.java @@ -519,7 +519,7 @@ public class ShellyChannelDefinitions { CHANNEL_SENSOR_VIBRATION); } // Create tilt for DW/DW2, for BLU DW create channel even tilt is currently not reported - if (sdata.accel != null || (profile.isBlu && sdata.lux != null)) { + if (sdata.accel != null || (profile.isBlu && profile.isDW && sdata.lux != null)) { addChannel(thing, newChannels, sdata.accel.tilt != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TILT); } @@ -670,7 +670,7 @@ public class ShellyChannelDefinitions { } description = getText(PREFIX_CHANNEL + typeId + ".description"); if (description.contains(PREFIX_CHANNEL)) { - description = ""; + description = ""; // no resource found } } diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/config2.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/config2.xml index bc212f828..ceccff2a0 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/config2.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/config2.xml @@ -96,10 +96,6 @@ @text/thing-type.config.shelly.deviceIp.description network-address - - - @text/thing-type.config.shelly.userId.description - @text/thing-type.config.shelly.password.description diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/configblu.xml b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/configblu.xml index fa888ad7b..7886954bd 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/configblu.xml +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/config/configblu.xml @@ -7,7 +7,7 @@ - @text/thing-type.config.shelly.@text/thing-type.config.shelly.deviceAddress.label.description + @text/thing-type.config.shelly.deviceAddress.description diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties index e42353f1c..7af710eef 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties +++ b/bundles/org.openhab.binding.shelly/src/main/resources/OH-INF/i18n/shelly.properties @@ -42,7 +42,7 @@ message.event.triggered = Event triggered: {0} message.event.filtered = Event filtered: {0} message.coap.init.failed = Unable to start CoIoT: {0} message.discovery.disabled = Device is marked as non-discoverable, will be skipped -message.discovery.protected = Device {0} reported 'Access defined' (missing userid/password or incorrect). +message.discovery.protected = Device {0} is protected and reports 'Access denied', check userId/password message.discovery.failed = Device discovery of device with address {0} failed: {1} message.roller.calibrating = Device is not calibrated, use Shelly App to perform initial roller calibration. message.roller.favmissing = Roller position favorites are not supported by installed firmware or not configured in the Shelly App @@ -101,7 +101,7 @@ thing-type.shelly.shellyplussmoke.description = Shelly Plus Smoke - Smoke Detect thing-type.shelly.shellypluswdus.description = Shelly Wall Dimmer US Device # Wall displays -thing-type.shelly.shellywalldisplay.description = Shelly Plus Wall Display with sensors and input/output +thing-type.shelly.shellywalldisplay.description = Shelly Wall Display with sensors and input/output # Plus Mini Devices thing-type.shelly.shellyplusmini1.description = Shelly Plus Mini 1 - Single Relay Switch @@ -120,7 +120,7 @@ thing-type.shelly.shellyproem50.description = Shelly Pro EM-50 - 2xPower Meter + thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter # BLU devices -thing-type.shelly.shellypblubutton.description = Shelly BLU Button +thing-type.shelly.shellyblubutton.description = Shelly BLU Button thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor # Wall Displays diff --git a/bundles/org.openhab.binding.shelly/src/main/resources/sniplets/ov_device.html b/bundles/org.openhab.binding.shelly/src/main/resources/sniplets/ov_device.html index 3465237ea..c39596022 100644 --- a/bundles/org.openhab.binding.shelly/src/main/resources/sniplets/ov_device.html +++ b/bundles/org.openhab.binding.shelly/src/main/resources/sniplets/ov_device.html @@ -32,7 +32,7 @@ Device Mode${deviceMode} Firmware Version${firmwareVersion} Network Name${serviceName} - MAC Address${macAddress} + Device Address${macAddress} Discoverable${discoverable} WiFi Auto Recovery${wifiAutoRecovery} WiFi AP Roaming${apRoamingMode}