diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md
index 406cffc19..fde35de2e 100644
--- a/bundles/org.openhab.binding.shelly/README.md
+++ b/bundles/org.openhab.binding.shelly/README.md
@@ -1451,8 +1451,6 @@ See notes on discovery of Shelly BLU devices above.
| | lowBattery | Switch | yes | Low battery alert (< 20%) |
| device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet |
-
-
### Shelly BLU Door/Window Sensor (thing-type: shellybludw)
See notes on discovery of Shelly BLU devices above.
@@ -1467,7 +1465,7 @@ See notes on discovery of Shelly BLU devices above.
| | lowBattery | Switch | yes | Low battery alert (< 20%) |
| device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet |
-## Shelly BLU Motion Sensor (thing-type: shellyblumotion)
+### Shelly BLU Motion Sensor (thing-type: shellyblumotion)
See notes on discovery of Shelly BLU devices above.
diff --git a/bundles/org.openhab.binding.shelly/pom.xml b/bundles/org.openhab.binding.shelly/pom.xml
index 61c8dbf6c..429dc71bd 100644
--- a/bundles/org.openhab.binding.shelly/pom.xml
+++ b/bundles/org.openhab.binding.shelly/pom.xml
@@ -14,13 +14,4 @@
org.openhab.binding.shelly
openHAB Add-ons :: Bundles :: Shelly Binding Gen1+2
-
-
- org.eclipse.jetty.websocket
- websocket-server
- 9.4.46.v20220331
- compile
-
-
-
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 34957a2b4..1a8732b0a 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
@@ -120,6 +120,7 @@ public class ShellyBindingConstants {
public static final String PROPERTY_DEV_TYPE = "deviceType";
public static final String PROPERTY_DEV_MODE = "deviceMode";
public static final String PROPERTY_DEV_GEN = "deviceGeneration";
+ public static final String PROPERTY_DEV_AUTH = "deviceAuth";
public static final String PROPERTY_GW_DEVICE = "gatewayDevice";
public static final String PROPERTY_HWREV = "deviceHwRev";
public static final String PROPERTY_HWBATCH = "deviceHwBatch";
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java
index f0cf33be8..111f60e4a 100755
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/ShellyHandlerFactory.java
@@ -119,7 +119,7 @@ public class ShellyHandlerFactory extends BaseThingHandlerFactory {
ShellyBaseHandler handler = null;
if (thingType.equals(THING_TYPE_SHELLYPROTECTED_STR)) {
- logger.debug("{}: Create new thing of type {}Â using ShellyProtectedHandler", thing.getLabel(),
+ logger.debug("{}: Create new thing of type {} using ShellyProtectedHandler", thing.getLabel(),
thingTypeUID.toString());
handler = new ShellyProtectedHandler(thing, messages, bindingConfig, thingTable, coapServer, httpClient);
} else if (thingType.equals(THING_TYPE_SHELLYBULB_STR) || thingType.equals(THING_TYPE_SHELLYDUO_STR)
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 23cce5cff..e82314ae9 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
@@ -145,6 +145,7 @@ public class ShellyDeviceProfile {
device.hostname = device.mac.length() >= 12 ? "shelly-" + device.mac.toUpperCase().substring(6, 11)
: "unknown";
}
+ device.mode = getString(settings.mode).toLowerCase();
name = getString(settings.name);
hwRev = settings.hwinfo != null ? getString(settings.hwinfo.hwRevision) : "";
hwBatchId = settings.hwinfo != null ? getString(settings.hwinfo.batchId.toString()) : "";
@@ -418,4 +419,18 @@ public class ShellyDeviceProfile {
// If device is not yet intialized or the enabled property is missing we assume that CoIoT is enabled
return true;
}
+
+ public static String buildBluServiceName(String name, String mac) throws IllegalArgumentException {
+ String model = name.contains("-") ? substringBefore(name, "-") : name; // e.g. SBBT-02C or just SBDW
+ switch (model) {
+ case SHELLYDT_BLUBUTTON:
+ return (THING_TYPE_SHELLYBLUBUTTON_STR + "-" + mac).toLowerCase();
+ case SHELLYDT_BLUDW:
+ return (THING_TYPE_SHELLYBLUDW_STR + "-" + mac).toLowerCase();
+ case SHELLYDT_BLUMOTION:
+ return (THING_TYPE_SHELLYBLUMOTION_STR + "-" + mac).toLowerCase();
+ default:
+ throw new IllegalArgumentException("Unsupported BLU device model " + model);
+ }
+ }
}
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 7ed436345..41fb01813 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
@@ -120,6 +120,12 @@ public class ShellyHttpClient {
}
return apiResult.response; // successful
} catch (ShellyApiException e) {
+ if (e.isHttpAccessUnauthorized() && !profile.isGen2 && !basicAuth && !config.password.isEmpty()) {
+ logger.debug("{}: Access is unauthorized, auto-activate basic auth", thingName);
+ basicAuth = true;
+ apiResult = innerRequest(HttpMethod.GET, uri, null, "");
+ }
+
if (e.isConnectionError()
|| (!e.isTimeout() && !apiResult.isHttpServerError()) && !apiResult.isNotFound()
|| profile.hasBattery || (retries == 0)) {
@@ -129,9 +135,10 @@ public class ShellyHttpClient {
timeout = true;
timeoutErrors++; // count the retries
- logger.debug("{}: API Timeout, retry #{} ({})", thingName, timeoutErrors, e.toString());
-
retries--;
+ if (profile.alwaysOn) {
+ logger.debug("{}: API Timeout, retry #{} ({})", thingName, timeoutErrors, e.toString());
+ }
}
}
throw new ShellyApiException("API Timeout or inconsistent result"); // successful
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 3de692e22..48eab5fb5 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
@@ -49,6 +49,7 @@ import org.openhab.binding.shelly.internal.config.ShellyThingConfiguration;
import org.openhab.binding.shelly.internal.handler.ShellyColorUtils;
import org.openhab.binding.shelly.internal.handler.ShellyThingInterface;
import org.openhab.core.library.unit.Units;
+import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.types.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -241,7 +242,7 @@ public class Shelly1CoapHandler implements Shelly1CoapListener {
}
if (!coiotBound) {
thingHandler.updateProperties(PROPERTY_COAP_VERSION, sVersion);
- logger.debug("{}: CoIoT Version {}Â detected", thingName, iVersion);
+ logger.debug("{}: CoIoT Version {} detected", thingName, iVersion);
if (iVersion == COIOT_VERSION_1) {
coiot = new Shelly1CoIoTVersion1(thingName, thingHandler, blkMap, sensorMap);
} else if (iVersion == COIOT_VERSION_2) {
@@ -265,6 +266,13 @@ public class Shelly1CoapHandler implements Shelly1CoapListener {
}
}
+ // Don't change state to online when thing is in status config error
+ // (e.g. auth failed, but device sends COAP packets via multicast)
+ if (thingHandler.getThingStatusDetail() == ThingStatusDetail.CONFIGURATION_ERROR) {
+ logger.debug("{}: The device is not configuired correctly, skip Coap packet", thingName);
+ return;
+ }
+
// If we received a CoAP message successful the thing must be online
thingHandler.setThingOnline();
@@ -441,7 +449,7 @@ public class Shelly1CoapHandler implements Shelly1CoapListener {
List sensorUpdates = list.generic;
Map updates = new TreeMap();
- logger.debug("{}: {}Â CoAP sensor updates received", thingName, sensorUpdates.size());
+ logger.debug("{}: {} CoAP sensor updates received", thingName, sensorUpdates.size());
int failed = 0;
ShellyColorUtils col = new ShellyColorUtils();
for (int i = 0; i < sensorUpdates.size(); i++) {
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiClient.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiClient.java
index 7ff8a6992..0e687307b 100644
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiClient.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2ApiClient.java
@@ -507,7 +507,7 @@ public class Shelly2ApiClient extends ShellyHttpClient {
rs.isValid = sm.isValid = emeter.isValid = true;
if (cs.state != null) {
if (!getString(rs.state).equals(cs.state)) {
- logger.debug("{}: Roller status changed from {}Â to {}, updateChannels={}", thingName, rs.state,
+ logger.debug("{}: Roller status changed from {} to {}, updateChannels={}", thingName, rs.state,
mapValue(MAP_ROLLER_STATE, cs.state), updateChannels);
}
rs.state = mapValue(MAP_ROLLER_STATE, cs.state);
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 17efc1d84..c37a9c854 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
@@ -131,14 +131,13 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
@Override
public void initialize() throws ShellyApiException {
- if (!initialized) {
- rpcSocket = new Shelly2RpcSocket(thingName, thingTable, config.deviceIp);
- rpcSocket.addMessageHandler(this);
- initialized = true;
- } else {
+ if (initialized) {
logger.debug("{}: Disconnect Rpc Socket on initialize", thingName);
disconnect();
}
+ rpcSocket = new Shelly2RpcSocket(thingName, thingTable, config.deviceIp);
+ rpcSocket.addMessageHandler(this);
+ initialized = true;
}
@Override
@@ -1211,6 +1210,9 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
}
private void disconnect() {
+ if (rpcSocket.isConnected()) {
+ logger.debug("{}: Disconnect Rpc Socket", thingName);
+ }
rpcSocket.disconnect();
}
@@ -1220,8 +1222,10 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
@Override
public void close() {
- logger.debug("{}: Closing Rpc API (socket is {}, discovery={})", thingName,
- rpcSocket.isConnected() ? "connected" : "disconnected", discovery);
+ if (initialized || rpcSocket.isConnected()) {
+ logger.debug("{}: Closing Rpc API (socket is {}, discovery={})", thingName,
+ rpcSocket.isConnected() ? "connected" : "disconnected", discovery);
+ }
disconnect();
initialized = false;
}
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2RpcSocket.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2RpcSocket.java
index faff2738e..308ab06ed 100644
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2RpcSocket.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/Shelly2RpcSocket.java
@@ -206,18 +206,24 @@ public class Shelly2RpcSocket {
if (s.isOpen()) {
logger.debug("{}: Disconnecting WebSocket ({} -> {})", thingName, s.getLocalAddress(),
s.getRemoteAddress());
- s.disconnect();
}
+ s.disconnect();
s.close(StatusCode.NORMAL, "Socket closed");
session = null;
}
- client.stop();
} catch (Exception e) {
if (e.getCause() instanceof InterruptedException) {
logger.debug("{}: Unable to close socket - interrupted", thingName); // e.g. device was rebooted
} else {
logger.debug("{}: Unable to close socket", thingName, e);
}
+ } finally {
+ // make sure client is stopped / thread terminates / socket resource is free up
+ try {
+ client.stop();
+ } catch (Exception e) {
+ logger.debug("{}: Unable to close Web Socket", thingName, e);
+ }
}
}
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/ShellyBluApi.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/ShellyBluApi.java
index 7869b6fd7..5dbb81609 100644
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/ShellyBluApi.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api2/ShellyBluApi.java
@@ -15,7 +15,6 @@ package org.openhab.binding.shelly.internal.api2;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
import static org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.*;
-import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.ArrayList;
@@ -112,11 +111,11 @@ public class ShellyBluApi extends Shelly2ApiRpc {
public ShellySettingsDevice getDeviceInfo() throws ShellyApiException {
ShellySettingsDevice info = new ShellySettingsDevice();
info.hostname = !config.serviceName.isEmpty() ? config.serviceName : "";
- info.fw = "1234";
- info.type = "SBBT";
+ info.fw = "";
+ info.type = "BLU";
info.mac = config.deviceAddress;
info.auth = false;
- info.gen = 99;
+ info.gen = 2;
return info;
}
@@ -136,13 +135,13 @@ public class ShellyBluApi extends Shelly2ApiRpc {
profile.gateway = getThing().getProperty(PROPERTY_GW_DEVICE);
}
- ShellySettingsDevice device = getDeviceInfo();
+ profile.device = getDeviceInfo();
if (config.serviceName.isEmpty()) {
config.serviceName = getString(profile.device.hostname);
}
- profile.fwDate = substringBefore(device.fw, "/");
- profile.fwVersion = substringBefore(ShellyDeviceProfile.extractFwVersion(device.fw.replace("/", "/v")), "-");
- profile.status.update.oldVersion = profile.fwVersion;
+
+ // for now we have no API to get this information
+ profile.fwDate = profile.fwVersion = profile.status.update.oldVersion = "";
profile.status.hasUpdate = profile.status.update.hasUpdate = false;
if (profile.hasBattery) {
@@ -239,7 +238,7 @@ public class ShellyBluApi extends Shelly2ApiRpc {
}
logger.debug("{}: BLU Device discovered", thingName);
if (e.data.name != null) {
- profile.settings.name = buildBluServiceName(e.data.name, e.data.addr);
+ profile.settings.name = ShellyDeviceProfile.buildBluServiceName(e.data.name, e.data.addr);
}
break;
case SHELLY2_EVENT_BLUDATA:
@@ -317,18 +316,4 @@ public class ShellyBluApi extends Shelly2ApiRpc {
if (updated) {
}
}
-
- public static String buildBluServiceName(String name, String mac) throws IllegalArgumentException {
- String model = name.contains("-") ? substringBefore(name, "-") : name; // e.g. SBBT-02C or just SBDW
- switch (model) {
- case SHELLYDT_BLUBUTTON:
- return (THING_TYPE_SHELLYBLUBUTTON_STR + "-" + mac).toLowerCase();
- case SHELLYDT_BLUDW:
- return (THING_TYPE_SHELLYBLUDW_STR + "-" + mac).toLowerCase();
- case SHELLYDT_BLUMOTION:
- return (THING_TYPE_SHELLYBLUMOTION_STR + "-" + mac).toLowerCase();
- default:
- throw new IllegalArgumentException("Unsupported BLU device model " + model);
- }
- }
}
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 793b710f7..db5da2e1e 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
@@ -145,15 +145,18 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant {
boolean gen2 = "2".equals(service.getPropertyString("gen"));
ShellyApiInterface api = null;
+ boolean auth = false;
ShellySettingsDevice devInfo;
try {
api = gen2 ? new Shelly2ApiRpc(name, config, httpClient) : new Shelly1HttpApi(name, config, httpClient);
api.initialize();
devInfo = api.getDeviceInfo();
model = devInfo.type;
+ auth = devInfo.auth;
if (devInfo.name != null) {
deviceName = devInfo.name;
}
+
profile = api.getDeviceProfile(thingType, devInfo);
api.close();
logger.debug("{}: Shelly settings : {}", name, profile.settingsJson);
@@ -191,6 +194,7 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant {
addProperty(properties, PROPERTY_DEV_TYPE, thingType);
addProperty(properties, PROPERTY_DEV_GEN, gen2 ? "2" : "1");
addProperty(properties, PROPERTY_DEV_MODE, mode);
+ addProperty(properties, PROPERTY_DEV_AUTH, auth ? "yes" : "no");
logger.debug("{}: Adding Shelly {}, UID={}", name, deviceName, thingUID.getAsString());
String thingLabel = deviceName.isEmpty() ? name + " - " + address
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 2871943ed..0daed7b48 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
@@ -187,21 +187,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
config.eventsSensorReport, config.eventsCoIoT, bindingConfig.autoCoIoT);
start = initializeThing();
} catch (ShellyApiException e) {
- ShellyApiResult res = e.getApiResult();
- String mid = "";
- if (e.isJsonError()) { // invalid JSON format
- mid = "offline.status-error-unexpected-error";
- start = false;
- } else if (isAuthorizationFailed(res)) {
- mid = "offline.conf-error-access-denied";
- start = false;
- } else if (profile.alwaysOn && e.isConnectionError()) {
- mid = "offline.status-error-connect";
- }
- if (!mid.isEmpty()) {
- setThingOffline(ThingStatusDetail.COMMUNICATION_ERROR, mid, e.toString());
- }
- logger.debug("{}: Unable to initialize: {}, retrying later", thingName, e.toString());
+ start = handleApiException(e);
} catch (IllegalArgumentException e) {
logger.debug("{}: Unable to initialize, retrying later", thingName, e);
} finally {
@@ -215,6 +201,43 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
}, 2, TimeUnit.SECONDS);
}
+ private boolean handleApiException(ShellyApiException e) {
+ ShellyApiResult res = e.getApiResult();
+ ThingStatusDetail errorCode = ThingStatusDetail.COMMUNICATION_ERROR;
+ String status = "";
+ boolean retry = true;
+ if (e.isJsonError()) { // invalid JSON format
+ logger.debug("{}: Unable to parse API response: {}; json={}", thingName, res.getUrl(), res.response, e);
+ status = "offline.status-error-unexpected-error";
+ errorCode = ThingStatusDetail.CONFIGURATION_ERROR;
+ retry = false;
+ } else if (res.isHttpAccessUnauthorized()) {
+ status = "offline.conf-error-access-denied";
+ errorCode = ThingStatusDetail.CONFIGURATION_ERROR;
+ retry = false;
+ } else if (isWatchdogExpired()) {
+ status = "offline.status-error-watchdog";
+ } else if (res.httpCode >= 400) {
+ logger.debug("{}: Unexpected API result: {}/{}", thingName, res.httpCode, res.httpReason, e);
+ status = "offline.status-error-unexpected-api-result";
+ retry = false;
+ } else if (profile.alwaysOn && (e.isConnectionError() || res.isHttpTimeout())) {
+ status = "offline.status-error-connect";
+ }
+
+ if (!status.isEmpty()) {
+ setThingOffline(errorCode, status, e.toString());
+ } else {
+ logger.debug("{}: Unable to initialize: {}, retrying later", thingName, e.toString());
+ }
+
+ if (!retry) {
+ api.close();
+ }
+
+ return retry;
+ }
+
@Override
public ShellyThingConfiguration getThingConfig() {
return config;
@@ -464,10 +487,11 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
requestUpdates(1, false);
}
} catch (ShellyApiException e) {
- ShellyApiResult res = e.getApiResult();
- if (isAuthorizationFailed(res)) {
+ if (!handleApiException(e)) {
return;
}
+
+ ShellyApiResult res = e.getApiResult();
if (res.isNotCalibrtated()) {
logger.warn("{}: {}", thingName, messages.get("roller.calibrating"));
} else {
@@ -554,35 +578,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
} catch (ShellyApiException e) {
// http call failed: go offline except for battery devices, which might be in
// sleep mode. Once the next update is successful the device goes back online
- String status = "";
- ShellyApiResult res = e.getApiResult();
- if (profile.alwaysOn && e.isConnectionError()) {
- status = "offline.status-error-connect";
- } else if (res.isHttpAccessUnauthorized()) {
- 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 (e.isJSONException()) {
- status = "offline.status-error-unexpected-api-result";
- logger.debug("{}: Unable to parse API response: {}; json={}", thingName, res.getUrl(), res.response, e);
- } else if (res.isHttpTimeout()) {
- // Watchdog not started, e.g. device in sleep mode
- if (isThingOnline()) { // ignore when already offline
- status = "offline.status-error-watchdog";
- }
- } else {
- status = "offline.status-error-unexpected-api-result";
- logger.debug("{}: Unexpected API result: {}", thingName, res.response, e);
- }
-
- if (!status.isEmpty()) {
- setThingOffline(ThingStatusDetail.COMMUNICATION_ERROR, status);
- }
+ handleApiException(e);
} catch (NullPointerException | IllegalArgumentException e) {
logger.debug("{}: Unable to refresh status: {}", thingName, messages.get("statusupdate.failed"), e);
} finally {
@@ -631,7 +627,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
}
if (prf.isRoller && prf.settings.favorites != null) {
String channelId = mkChannelId(CHANNEL_GROUP_ROL_CONTROL, CHANNEL_ROL_CONTROL_FAV);
- logger.debug("{}: Adding {}Â roler favorite(s) to channel description", thingName,
+ logger.debug("{}: Adding {} roler favorite(s) to channel description", thingName,
prf.settings.favorites.size());
channelDefinitions.clearStateOptions(channelId);
int fid = 1;
@@ -1057,7 +1053,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
String minVersion = !gen2 ? SHELLY_API_MIN_FWVERSION : SHELLY2_API_MIN_FWVERSION;
if (version.compare(prf.fwVersion, minVersion) < 0) {
logger.warn("{}: {}", prf.device.hostname,
- messages.get("versioncheck.beta", prf.fwVersion, prf.fwDate));
+ messages.get("versioncheck.tooold", prf.fwVersion, prf.fwDate, minVersion));
}
}
if (!gen2 && bindingConfig.autoCoIoT && ((version.compare(prf.fwVersion, SHELLY_API_MIN_FWCOIOT)) >= 0)
@@ -1120,23 +1116,6 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
}
}
- /**
- * Checks the http response for authorization error.
- * If the authorization failed the binding can't access the device settings and determine the thing type. In this
- * case the thing type shelly-unknown is set.
- *
- * @param result exception details including the http respone
- * @return true if the authorization failed
- */
- protected boolean isAuthorizationFailed(ShellyApiResult result) {
- if (result.isHttpAccessUnauthorized()) {
- // If the device is password protected the API doesn't provide settings to the device settings
- setThingOffline(ThingStatusDetail.CONFIGURATION_ERROR, "offline.conf-error-access-denied");
- return true;
- }
- return false;
- }
-
/**
* Change type of this thing.
*
@@ -1363,11 +1342,11 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
properties.put(PROPERTY_SERVICE_NAME, config.serviceName);
String deviceName = getString(profile.settings.name);
properties.put(PROPERTY_SERVICE_NAME, config.serviceName);
- properties.put(PROPERTY_DEV_GEN, "1");
+ properties.put(PROPERTY_DEV_GEN, !profile.isGen2 ? "1" : "2");
+ properties.put(PROPERTY_DEV_AUTH, getBool(profile.device.auth) ? "yes" : "no");
if (!deviceName.isEmpty()) {
properties.put(PROPERTY_DEV_NAME, deviceName);
}
- properties.put(PROPERTY_DEV_GEN, !profile.isGen2 ? "1" : "2");
// add status properties
if (status.wifiSta != null) {
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBluSensorHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBluSensorHandler.java
index 0c392678d..8e097bf76 100644
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBluSensorHandler.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/handler/ShellyBluSensorHandler.java
@@ -13,7 +13,6 @@
package org.openhab.binding.shelly.internal.handler;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.*;
-import static org.openhab.binding.shelly.internal.api2.ShellyBluApi.buildBluServiceName;
import static org.openhab.binding.shelly.internal.discovery.ShellyThingCreator.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import static org.openhab.core.thing.Thing.PROPERTY_MODEL_ID;
@@ -23,6 +22,7 @@ import java.util.TreeMap;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
+import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api1.Shelly1CoapServer;
import org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.Shelly2NotifyEvent;
import org.openhab.binding.shelly.internal.config.ShellyBindingConfiguration;
@@ -54,7 +54,7 @@ public class ShellyBluSensorHandler extends ShellyBaseHandler {
public static void addBluThing(String gateway, Shelly2NotifyEvent e, ShellyThingTable thingTable) {
String model = substringBefore(getString(e.data.name), "-").toUpperCase();
- String mac = e.data.addr.replace(":", "");
+ String mac = e.data.addr.replaceAll(":", "");
String ttype = "";
logger.debug("{}: Create thing for new BLU device {}: {} / {}", gateway, e.data.name, model, mac);
ThingTypeUID tuid;
@@ -75,7 +75,7 @@ public class ShellyBluSensorHandler extends ShellyBaseHandler {
logger.debug("{}: Unsupported BLU device model {}, MAC={}", gateway, model, mac);
return;
}
- String serviceName = buildBluServiceName(model, mac);
+ String serviceName = ShellyDeviceProfile.buildBluServiceName(getString(e.data.name), mac);
Map properties = new TreeMap<>();
addProperty(properties, PROPERTY_MODEL_ID, model);
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 cbac83ffc..fc648d2eb 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
@@ -78,7 +78,7 @@ public class ShellyComponents {
if (status.tmp != null && getBool(status.tmp.isValid) && !thingHandler.getProfile().isSensor
&& status.tmp.tC != SHELLY_API_INVTEMP) {
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
- toQuantityType(getDouble(status.tmp.tC), DIGITS_NONE, SIUnits.CELSIUS));
+ toQuantityType(getDouble(status.tmp.tC), DIGITS_TEMP, SIUnits.CELSIUS));
} else if (status.temperature != null && status.temperature != SHELLY_API_INVTEMP) {
thingHandler.updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ITEMP,
toQuantityType(getDouble(status.temperature), DIGITS_NONE, SIUnits.CELSIUS));
diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOverviewPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOverviewPage.java
index ff4307699..93c8bd1ee 100644
--- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOverviewPage.java
+++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOverviewPage.java
@@ -64,7 +64,7 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage {
String action = getUrlParm(parameters, URLPARM_ACTION).toLowerCase();
String uidParm = getUrlParm(parameters, URLPARM_UID).toLowerCase();
- logger.debug("Generating overview for {}Â devices", getThingHandlers().size());
+ logger.debug("Generating overview for {} devices", getThingHandlers().size());
String html = "";
Map properties = new HashMap<>();
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 6f03bfc79..7ecaa6232 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
@@ -315,7 +315,7 @@ public class ShellyChannelDefinitions {
addChannel(thing, add, profile.settings.sleepTime != null, CHGR_SENSOR, CHANNEL_SENSOR_SLEEPTIME);
// If device has more than 1 meter the channel accumulatedWatts receives the accumulated value
- boolean accuChannel = profile.numMeters > 1 && !profile.isRoller && !profile.isRGBW2;
+ boolean accuChannel = profile.hasRelays && profile.numMeters > 1 && !profile.isRoller && !profile.isRGBW2;
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS);
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL);
addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED);
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 caa4b4243..8ec3b279b 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
@@ -34,7 +34,7 @@ message.versioncheck.update = INFO: New firmware available: current version: {0}
message.versioncheck.autocoiot = INFO: Firmware is full-filling the minimum version to auto-enable CoIoT
message.init.noipaddress = Unable to detect local IP address. Please make sure that IPv4 is enabled for this interface and check openHAB Network Configuration.
message.command.failed = ERROR: Unable to process command {0} for channel {1}
-message.command.init = Thing not yet initialized, command {0} triggered initialization
+message.command.init = Thing not yet initialized, command {0} triggered initialization
message.status.unknown.initializing = Initializing or device in sleep mode.
message.statusupdate.failed = Unable to update status
message.status.managerstarted = Shelly Manager started at http(s)://{0}:{1}/shelly/manager
@@ -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.shellyblubutton.description = Shelly BLU Button
+thing-type.shelly.shellyblubutton.description = Shelly BLU Button 1
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
thing-type.shelly.shellyblumotion.description = Shelly BLU Motion Sensor
@@ -247,7 +247,7 @@ channel-type.shelly.temperature4.description = Temperature of external Sensor #4
channel-type.shelly.temperature5.label = Temperature 5
channel-type.shelly.temperature6.description = Temperature of external Sensor #5
channel-type.shelly.targetTemp.label = Target Temperature
-channel-type.shelly.targetTemp.description = Target Temperature in °C to be reached in auto-temperature mode
+channel-type.shelly.targetTemp.description = Target Temperature in °C to be reached in auto-temperature mode
channel-type.shelly.humidity.label = Humidity
channel-type.shelly.humidity.description = Relative humidity (0..100%)
channel-type.shelly.rollerShutter.label = Roller Control (0=open, 100=closed)