[shelly] Misc changes (small fixes, log improvements, hardened leak prevention on (#15922)
* Misc changes (same fixes, log improvements, hardened leak prevention on exceptions) --------- Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
parent
a31b1578be
commit
a13fd80bfe
|
@ -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.
|
||||
|
||||
|
|
|
@ -14,13 +14,4 @@
|
|||
<artifactId>org.openhab.binding.shelly</artifactId>
|
||||
<name>openHAB Add-ons :: Bundles :: Shelly Binding Gen1+2</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-server</artifactId>
|
||||
<version>9.4.46.v20220331</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<CoIotSensor> sensorUpdates = list.generic;
|
||||
Map<String, State> updates = new TreeMap<String, State>();
|
||||
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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
if (initialized || rpcSocket.isConnected()) {
|
||||
logger.debug("{}: Closing Rpc API (socket is {}, discovery={})", thingName,
|
||||
rpcSocket.isConnected() ? "connected" : "disconnected", discovery);
|
||||
}
|
||||
disconnect();
|
||||
initialized = false;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<String, Object> properties = new TreeMap<>();
|
||||
addProperty(properties, PROPERTY_MODEL_ID, model);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<String, String> properties = new HashMap<>();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue