diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md index 459036cb5..501e9dd32 100644 --- a/bundles/org.openhab.binding.shelly/README.md +++ b/bundles/org.openhab.binding.shelly/README.md @@ -17,6 +17,7 @@ The binding gets in sync with the next status refresh. Refer to [Advanced Users](doc/AdvancedUsers.md) for more information on openHAB Shelly integration, e.g. firmware update, network communication or log filtering. Also check out the [Shelly Manager](doc/ShellyManager.md), which + - provides detailed information on your Shellys - helps to diagnose WiFi issues or device instabilities - includes some common actions and @@ -276,6 +277,7 @@ Check the channel definitions for the various devices to see if the device suppo You could use the Shelly App to set the timing for those events. If you want to use those events triggering a rule: + - If a physical switch is connected to the Shelly use the input channel(`input` or `input1`/`input2`) to trigger a rule - For a momentary button use the `button` trigger channel as trigger, channels `lastEvent` and `eventCount` will provide details on the event @@ -309,7 +311,7 @@ A new alarm will be triggered on a new condition or every 5 minutes if the condi |BATTERY |Device reported an update to the battery status. | |TEMP_UNDER |Below "temperature under" threshold | |TEMP_OVER |Above "temperature over" threshold | - +|VIBRATION |A vibration/tamper was detected (DW2 only) | Refer to section [Full Example:shelly.rules](#shelly-rules) for examples how to catch alarm triggers in openHAB rules @@ -803,6 +805,7 @@ You can define 2 items (1 Switch, 1 Number) mapping to the same channel, see exa | |lastError |String |yes |Last device error. | |battery |batteryLevel |Number |yes |Battery Level in % | | |lowBattery |Switch |yes |Low battery alert (< 20%) | +|device |alarm |Trigger |yes |Will receive trigger VIBRATION if DW2 detects vibration | ### Shelly Motion (thing-type: shellymotion) @@ -1090,8 +1093,8 @@ when Channel "shelly:shelly25-roller:XXXXXX:device#alarm" triggered then if (receivedEvent !== null) { // A (channel) event triggered the rule - eventSource = receivedEvent.getChannel().asString - eventType = receivedEvent.getEvent() + eventSource = triggeredChannel + eventType = receivedEvent ... } end 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 09ca61a53..16256635e 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 @@ -191,8 +191,6 @@ public class ShellyBindingConstants { public static final String PROPERTY_UPDATE_NEW_VERS = "updateNewVersion"; public static final String PROPERTY_COAP_DESCR = "coapDeviceDescr"; public static final String PROPERTY_COAP_VERSION = "coapVersion"; - public static final String PROPERTY_STATS_TIMEOUTS = "statsTimeoutErrors"; - public static final String PROPERTY_STATS_TRECOVERED = "statsTimeoutsRecovered"; public static final String PROPERTY_COIOTAUTO = "coiotAutoEnable"; // Relay @@ -337,6 +335,7 @@ public class ShellyBindingConstants { public static final String ALARM_TYPE_LOADERR = "LOAD_ERROR"; public static final String ALARM_TYPE_SENSOR_ERROR = "SENSOR_ERROR"; public static final String ALARM_TYPE_LOW_BATTERY = "LOW_BATTERY"; + public static final String EVENT_TYPE_VIBRATION = "VIBRATION"; // Event types public static final String EVENT_TYPE_RELAY = "relay"; @@ -364,4 +363,5 @@ 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 } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiException.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiException.java index 0e7df9d5a..0cf28c4d1 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiException.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiException.java @@ -34,7 +34,7 @@ public class ShellyApiException extends Exception { private static final long serialVersionUID = -5809459454769761821L; private ShellyApiResult apiResult = new ShellyApiResult(); - private static String NONE = "none"; + private static final String NONE = "none"; public ShellyApiException(Exception exception) { super(exception); @@ -117,7 +117,7 @@ public class ShellyApiException extends Exception { } private boolean isEmpty() { - return nonNullString(super.getMessage()).equals(NONE); + return NONE.equals(nonNullString(super.getMessage())); } private static String nonNullString(@Nullable String s) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java index ca1d1379a..d103ee9b1 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyApiJsonDTO.java @@ -379,9 +379,6 @@ public class ShellyApiJsonDTO { public String pushLongUrl; // to access when roller stopped @SerializedName("shortpush_url") public String pushShortUrl; // to access when roller stopped - - public Boolean schedule; - // ArrayList schedule_rules; } public static class ShellySettingsDimmer { @@ -442,8 +439,6 @@ public class ShellyApiJsonDTO { public Boolean isValid; @SerializedName("safety_switch") public Boolean safetySwitch; - public Boolean schedule; - // ArrayList schedule_rules; // not used for now @SerializedName("obstacle_mode") public String obstaclMode; // SHELLY_OBSTMODE_ @SerializedName("obstacle_action") @@ -468,7 +463,8 @@ public class ShellyApiJsonDTO { public Boolean ison; // true: output is ON public Integer brightness; public Integer transition; - public String default_state; + @SerializedName("default_state") + public String defaultState; @SerializedName("auto_on") public Double autoOn; // Automatic flip back timer, seconds. Will engage after turning Shelly1 OFF. @SerializedName("auto_off") @@ -565,20 +561,14 @@ public class ShellyApiJsonDTO { public ShellySensorSleepMode sleepMode; // FW 1.6 @SerializedName("external_power") public Integer externalPower; // H&T FW 1.6, seems to be the same like charger for the Sense - public Boolean debug_enable; // FW 1.10+ + @SerializedName("debug_enable") // FW 1.10+ + public Boolean debugEnable; public String timezone; public Double lat; public Double lng; public Boolean tzautodetect; public String time; - // @SerializedName("tz_utc_offset") - // public Integer tzUTCOoffset; // FW 1.6+ - // @SerializedName("tz_dst") - // public Boolean tzDdst; // FW 1.6+ - // @SerializedName("tz_dst_auto") - // public Boolean tzDstAuto; // FW 1.6+ - // public Long unixtime; // FW 1.6+ public ShellySettingsHwInfo hwinfo; public String mode; @@ -619,15 +609,6 @@ public class ShellyApiJsonDTO { @SerializedName("vibration_url") public String vibrationUrl; // URL reports when DW detects vibration FW 1.6.5+ - // @SerializedName("tilt_enabled") - // public Boolean tiltEnabled; // Whether tilt monitoring is activated - // @SerializedName("tilt_calibrated") - // public Boolean tiltCalibrated; // Whether calibration data is valid - // @SerializedName("vibration_enabled") - // public Boolean vibrationEnabled; // Whether vibration monitoring is activated - // @SerializedName("reverse_open_close") - // public Boolean reverseOpenClose; // Whether to reverse which position the sensor consideres "open" - // Gas FW 1.7 @SerializedName("set_volume") public Integer volume; // Speaker volume for alarm @@ -700,8 +681,6 @@ public class ShellyApiJsonDTO { public Integer input; // RGBW2 has no JSON array public ArrayList inputs; public ArrayList lights; - // @SerializedName("night_mode") // FW 1.5.7+ - // public ShellySettingsNightMode nightMode; public ArrayList dimmers; public ArrayList meters; public ArrayList emeters; @@ -735,27 +714,6 @@ public class ShellyApiJsonDTO { public static class ShellySettingsInput { @SerializedName("btn_type") public String btnType; - - // attributes not yet processed - // public String name; - // @SerializedName("btn_reverse") - // public Integer btnReverse; - // @SerializedName("btn_on_url") - // public String btnOnUrl; - // @SerializedName("btn_off_url") - // public String btnOffUrl; - // @SerializedName("shortpush_url") - // public String shortpushUrl; - // @SerializedName("longpush_url") - // public String longpushUrl; - // @SerializedName("double_shortpush_url") - // public String doubleShortpushUrl; - // @SerializedName("triple_shortpush_url") - // public String tripleShortpushUrl; - // @SerializedName("shortpush_longpush_url") - // public String shortpushLongpushUrl; - // @SerializedName("longpush_shortpush_url") - // public String longpushShortpushUrl; } public static class ShellyControlRelay { @@ -791,12 +749,6 @@ public class ShellyApiJsonDTO { public Boolean ison; // Whether output channel is on or off public String mode; // color or white - valid only for Bulb and RGBW2 even Dimmer returns it also public Integer brightness; // brightness: 0.100% - // @SerializedName("has_timer") - // public Boolean hasTimer; // Whether a timer is currently armed for this channel - // @SerializedName("timer_remaining") - // public Integer timerRemaining; - // public Integer wgite; - // public Integer temp; // light temp } public static class ShellyStatusRelay { @@ -804,10 +756,7 @@ public class ShellyApiJsonDTO { @SerializedName("wifi_sta") public ShellySettingsWiFiNetwork wifiSta; // WiFi status - // public ShellyStatusCloud cloud; // Cloud status - // public ShellyStatusMqtt mqtt; // mqtt status public ShellySettingsCoiot coiot; // Firmware 1.6+ - // public String time; // current time public Integer serial; public String mac; // MAC public ArrayList relays; // relay status @@ -821,30 +770,11 @@ public class ShellyApiJsonDTO { public Double temperature; // device temp acc. on the selected temp unit public ShellyStatusSensor.ShellySensorTmp tmp; - - @SerializedName("has_update") - public Boolean hasUpdate; // If a newer firmware version is available - public ShellySettingsUpdate update; // /status/firmware value - - @SerializedName("ram_total") - public Integer ramTotal; // Total and available amount of system memory in bytes - @SerializedName("ram_free") - public Integer ramFree; - @SerializedName("fs_size") - public Integer fsSize; - @SerializedName("fs_free") - public Integer fsFree; // Total and available amount of file system space in bytes - public Integer uptime; // econds elapsed since boot } public static class ShellyStatusDimmer { @SerializedName("wifi_sta") public ShellySettingsWiFiNetwork wifiSta; // WiFi status - // public ShellyStatusCloud cloud; // Cloud status - // public ShellyStatusMqtt mqtt; // mqtt status - public String time; // current time - public Integer serial; - public String mac; // MAC public ArrayList lights; // relay status public ArrayList meters; // current meter value @@ -853,21 +783,6 @@ public class ShellyApiJsonDTO { public Boolean loaderror; public Boolean overload; - - @SerializedName("has_update") - public Boolean hasUpdate; // If a newer firmware version is available - public ShellySettingsUpdate update; // /status/firmware value - - @SerializedName("ram_total") - public Integer ramTotal; // Total and available amount of system memory in - // bytes - @SerializedName("ram_free") - public Integer ramFree; - @SerializedName("fs_size") - public Integer fsSize; - @SerializedName("fs_free") - public Integer fsFree; // Total and available amount of file system space in bytes - public Integer uptime; // seconds elapsed since boot } public static class ShellyControlRoller { 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 45cc461cf..555f3d294 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 @@ -45,7 +45,7 @@ import com.google.gson.Gson; @NonNullByDefault public class ShellyDeviceProfile { private final Logger logger = LoggerFactory.getLogger(ShellyDeviceProfile.class); - private final static Pattern VERSION_PATTERN = Pattern.compile("v\\d+\\.\\d+\\.\\d+(-[a-z0-9]*)?"); + private static final Pattern VERSION_PATTERN = Pattern.compile("v\\d+\\.\\d+\\.\\d+(-[a-z0-9]*)?"); public boolean initialized = false; // true when initialized @@ -131,6 +131,7 @@ public class ShellyDeviceProfile { extFeatures = version.compare(fwVersion, SHELLY_API_FW_110) >= 0; discoverable = (settings.discoverable == null) || settings.discoverable; + isRoller = mode.equalsIgnoreCase(SHELLY_MODE_ROLLER); inColor = isLight && mode.equalsIgnoreCase(SHELLY_MODE_COLOR); numRelays = !isLight ? getInteger(settings.device.numOutputs) : 0; @@ -184,8 +185,6 @@ public class ShellyDeviceProfile { } isDimmer = deviceType.equalsIgnoreCase(SHELLYDT_DIMMER) || deviceType.equalsIgnoreCase(SHELLYDT_DIMMER2); - isRoller = mode.equalsIgnoreCase(SHELLY_MODE_ROLLER); - isBulb = thingType.equals(THING_TYPE_SHELLYBULB_STR); isDuo = thingType.equals(THING_TYPE_SHELLYDUO_STR) || thingType.equals(THING_TYPE_SHELLYVINTAGE_STR) || thingType.equals(THING_TYPE_SHELLYDUORGBW_STR); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java index df7bd8a94..13c5b8ede 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/api/ShellyHttpApi.java @@ -246,8 +246,8 @@ public class ShellyHttpApi { } public ShellySettingsLogin setLoginCredentials(String user, String password) throws ShellyApiException { - return callApi(SHELLY_URL_SETTINGS + "/login?enabled=yes&username=" + user + "&password=" + password, - ShellySettingsLogin.class); + return callApi(SHELLY_URL_SETTINGS + "/login?enabled=yes&username=" + urlEncode(user) + "&password=" + + urlEncode(password), ShellySettingsLogin.class); } public String getCoIoTDescription() throws ShellyApiException { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java index 723f76079..eaa1881c3 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTProtocol.java @@ -76,9 +76,6 @@ public class ShellyCoIoTProtocol { protected boolean handleStatusUpdate(List sensorUpdates, CoIotDescrSen sen, CoIotSensor s, Map updates, ShellyColorUtils col) { // Process status information and convert into channel updates - // Integer rIndex = Integer.parseInt(sen.links) + 1; - // String rGroup = getProfile().numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL - // : CHANNEL_GROUP_RELAY_CONTROL + rIndex; int rIndex = getIdFromBlk(sen); String rGroup = getProfile().numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL : CHANNEL_GROUP_RELAY_CONTROL + rIndex; @@ -130,8 +127,10 @@ public class ShellyCoIoTProtocol { s.value == 1 ? OnOffType.ON : OnOffType.OFF); break; case "vibration": // DW with FW1.6.5+ - updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, - s.value == 1 ? OnOffType.ON : OnOffType.OFF); + if (s.value == 1) { + thingHandler.triggerChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE, + EVENT_TYPE_VIBRATION); + } break; case "luminositylevel": // + updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ILLUM, getStringType(s.valueStr)); @@ -166,7 +165,7 @@ public class ShellyCoIoTProtocol { updateChannel(updates, CHANNEL_GROUP_COLOR_CONTROL, CHANNEL_COLOR_GAIN, ShellyColorUtils.toPercent((int) s.value, SHELLY_MIN_GAIN, SHELLY_MAX_GAIN)); break; - case "sensorerror": // + + case "sensorerror": updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ERROR, getStringType(s.valueStr)); break; default: diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java index c650efeea..3a1ed6c07 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion1.java @@ -177,8 +177,15 @@ public class ShellyCoIoTVersion1 extends ShellyCoIoTProtocol implements ShellyCo toQuantityType(s.value, DIGITS_NONE, Units.DEGREE_ANGLE)); break; case "vibration": // DW with FW1.6.5+ - updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, - s.value == 1 ? OnOffType.ON : OnOffType.OFF); + if (profile.isMotion) { + // handle as status + updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, + s.value == 1 ? OnOffType.ON : OnOffType.OFF); + } else if (s.value == 1) { + // handle as event + thingHandler.triggerChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE, + EVENT_TYPE_VIBRATION); + } break; case "temp": // Shelly Bulb case "colortemperature": // Shelly Duo diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java index a239f41e0..c600c1c9b 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoIoTVersion2.java @@ -103,7 +103,10 @@ public class ShellyCoIoTVersion2 extends ShellyCoIoTProtocol implements ShellyCo // skip, could check against thing mode... break; - case "1101": // S, output, 0/1 + case "1101": // relay_0: output, 0/1 + case "1201": // relay_1: output, 0/1 + case "1301": // relay_2: output, 0/1 + case "1401": // relay_3: output, 0/1 updatePower(profile, updates, rIndex, sen, s, sensorUpdates); break; case "1102": // roler_0: S, roller, open/close/stop -> roller state @@ -316,8 +319,14 @@ public class ShellyCoIoTVersion2 extends ShellyCoIoTProtocol implements ShellyCo updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE, getStringType(s.valueStr)); break; case "6110": // A, vibration, 0/1, -1=unknown - updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, - value == 1 ? OnOffType.ON : OnOffType.OFF); + if (profile.isMotion) { + // handle as status + updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, + s.value == 1 ? OnOffType.ON : OnOffType.OFF); + } else if (s.value == 1) { + // handle as event + thingHandler.triggerChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ALARM, EVENT_TYPE_VIBRATION); + } break; case "9102": // EV, wakeupEvent, battery/button/periodic/poweron/sensor/ext_power, "unknown"=unknown if (s.valueArray.size() > 0) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java index a35dc157f..ff3fe72d7 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/coap/ShellyCoapHandler.java @@ -133,8 +133,9 @@ public class ShellyCoapHandler implements ShellyCoapListener { .setTimeout((long) SHELLY_API_TIMEOUT_MS).useNONs().setEndpoint(coapServer.getEndpoint()); @Nullable Endpoint endpoint = null; - if (statusClient != null) { - endpoint = statusClient.getEndpoint(); + CoapClient client = statusClient; + if (client != null) { + endpoint = client.getEndpoint(); } if ((endpoint == null) || !endpoint.isStarted()) { logger.warn("{}: Unable to initialize CoAP access (network error)", thingName); 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 72c714887..f6978d56e 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 @@ -115,8 +115,11 @@ public class ShellyDiscoveryParticipant implements MDNSDiscoveryParticipant { Map properties = new TreeMap<>(); name = service.getName().toLowerCase(); - address = service.getHostAddress(); - if ((address == null) || address.isEmpty()) { + String[] hostAddresses = service.getHostAddresses(); + if ((hostAddresses != null) && (hostAddresses.length > 0)) { + address = hostAddresses[0]; + } + if (address.isEmpty()) { logger.trace("{}: Shelly device discovered with empty IP address (service-name={})", name, service); return null; } 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 5307e6a37..5d1642f20 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 @@ -101,8 +101,6 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL private int skipUpdate = 0; private boolean refreshSettings = false; - private @Nullable ScheduledFuture asyncButtonRelease; - // delay before enabling channel private final int cacheCount = UPDATE_SETTINGS_INTERVAL_SECONDS / UPDATE_STATUS_INTERVAL_SECONDS; protected final ShellyChannelCache cache; @@ -111,6 +109,7 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL private String localPort = ""; private String lastWakeupReason = ""; + private int vibrationFilter = 0; /** * Constructor @@ -274,9 +273,7 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL logger.debug("{}: Unable to set CoIoT peer: {}", thingName, e.toString()); } } else if (!devpeer.isEmpty() && !devpeer.equals(ourpeer)) { - logger.warn("{}: CoIoT peer in device settings does not point this to this host, disabling CoIoT", - thingName); - config.eventsCoIoT = autoCoIoT = false; + logger.warn("{}: CoIoT peer in device settings does not point this to this host", thingName); } } if (autoCoIoT) { @@ -385,6 +382,12 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL try { boolean updated = false; + if (vibrationFilter > 0) { + vibrationFilter--; + logger.debug("{}: Vibration events are absorbed for {} more seconds", thingName, + vibrationFilter * UPDATE_STATUS_INTERVAL_SECONDS); + } + skipUpdate++; ThingStatus thingStatus = getThing().getStatus(); if (refreshSettings || (scheduledUpdates > 0) || (skipUpdate % skipCount == 0)) { @@ -483,7 +486,7 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL updateStatus(ThingStatus.ONLINE); // request 3 updates in a row (during the first 2+3*3 sec) - requestUpdates(profile.alwaysOn ? 3 : 1, channelsCreated == false); + requestUpdates(profile.alwaysOn ? 3 : 1, !channelsCreated); } restartWatchdog(); } @@ -575,8 +578,9 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL */ private boolean checkRestarted(ShellySettingsStatus status) { - if (profile.isInitialized() && (status.uptime < stats.lastUptime || !profile.status.update.oldVersion.isEmpty() - && !status.update.oldVersion.equals(profile.status.update.oldVersion))) { + if (profile.isInitialized() && profile.alwaysOn /* exclude battery powered devices */ + && (status.uptime < stats.lastUptime || !profile.status.update.oldVersion.isEmpty() + && !status.update.oldVersion.equals(profile.status.update.oldVersion))) { updateProperties(profile, status); return true; } @@ -706,13 +710,10 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL updateChannel(group, CHANNEL_SENSOR_ILLUM, getStringType(event)); break; - case SHELLY_EVENT_VIBRATION: - updateChannel(group, CHANNEL_SENSOR_VIBRATION, OnOffType.ON); - break; - case SHELLY_EVENT_ALARM_MILD: // Shelly Gas case SHELLY_EVENT_ALARM_HEAVY: case SHELLY_EVENT_ALARM_OFF: + case SHELLY_EVENT_VIBRATION: // DW2 channel = CHANNEL_SENSOR_ALARM_STATE; payload = event.toUpperCase(); break; @@ -1195,7 +1196,21 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL } public void triggerChannel(String group, String channel, String payload) { - triggerChannel(mkChannelId(group, channel), payload); + String triggerCh = mkChannelId(group, channel); + logger.debug("{}: Send event {} to channel {}", thingName, triggerCh, payload); + if (EVENT_TYPE_VIBRATION.contentEquals(payload)) { + if (vibrationFilter == 0) { + vibrationFilter = VIBRATION_FILTER_SEC / UPDATE_STATUS_INTERVAL_SECONDS + 1; + logger.debug("{}: Duplicate vibration events will be absorbed for the next {} sec", thingName, + vibrationFilter * UPDATE_STATUS_INTERVAL_SECONDS); + } else { + logger.debug("{}: Vibration event absorbed, {} sec remaining", thingName, + vibrationFilter * UPDATE_STATUS_INTERVAL_SECONDS); + return; + } + } + + triggerChannel(triggerCh, payload); } public void stop() { @@ -1206,11 +1221,6 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL statusJob = null; logger.debug("{}: Shelly statusJob stopped", thingName); } - job = asyncButtonRelease; - if (job != null) { - job.cancel(true); - asyncButtonRelease = null; - } coap.stop(); profile.initialized = false; 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 8b8ab9d9b..82d1e661a 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 @@ -300,8 +300,6 @@ public class ShellyComponents { if (sdata.accel != null) { updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TILT, toQuantityType(getDouble(sdata.accel.tilt.doubleValue()), DIGITS_NONE, Units.DEGREE_ANGLE)); - updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, - getInteger(sdata.accel.vibration) == 1 ? OnOffType.ON : OnOffType.OFF); } if (sdata.flood != null) { updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_FLOOD, @@ -365,8 +363,6 @@ public class ShellyComponents { updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_MOTION_TS, getTimestamp(getString(profile.settings.timezone), timestamp)); } - updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION, - getOnOff(sdata.sensor.vibration)); } updated |= thingHandler.updateInputs(status); diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManager.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManager.java index 388b2a36b..5ebf9b70b 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManager.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManager.java @@ -34,11 +34,9 @@ import org.osgi.service.cm.ConfigurationAdmin; @NonNullByDefault public class ShellyManager { private final Map pages = new LinkedHashMap<>(); - private final ShellyHandlerFactory handlerFactory; public ShellyManager(ConfigurationAdmin configurationAdmin, ShellyTranslationProvider translationProvider, HttpClient httpClient, String localIp, int localPort, ShellyHandlerFactory handlerFactory) { - this.handlerFactory = handlerFactory; pages.put(SHELLY_MGR_OVERVIEW_URI, new ShellyManagerOverviewPage(configurationAdmin, translationProvider, httpClient, localIp, localPort, handlerFactory)); pages.put(SHELLY_MGR_ACTION_URI, new ShellyManagerActionPage(configurationAdmin, translationProvider, diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java index 38ede361c..017fcae9f 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerActionPage.java @@ -92,7 +92,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { refreshTimer = 3; break; case ACTION_RESTART: - if (update.equalsIgnoreCase("yes")) { + if ("yes".equalsIgnoreCase(update)) { message = getMessageP("action.restart.info", MCINFO); actionButtonLabel = "Ok"; new Thread(() -> { // schedule asynchronous reboot @@ -116,7 +116,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { break; } - if (!update.equalsIgnoreCase("yes")) { + if (!"yes".equalsIgnoreCase(update)) { ShellySettingsLogin status = api.getLoginSettings(); message = getMessage("action.protect.status", getBool(status.enabled) ? "enabled" : "disabled", status.username) @@ -137,7 +137,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { } String peer = getString(profile.settings.coiot.peer); - boolean mcast = peer.isEmpty() || peer.equalsIgnoreCase(SHELLY_COIOT_MCAST); + boolean mcast = peer.isEmpty() || SHELLY_COIOT_MCAST.equalsIgnoreCase(peer); String newPeer = mcast ? localIp + ":" + ShellyCoapJSonDTO.COIOT_PORT : SHELLY_COIOT_MCAST; String displayPeer = mcast ? newPeer : "Multicast"; @@ -147,7 +147,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { break; } - if (!update.equalsIgnoreCase("yes")) { + if (!"yes".equalsIgnoreCase(update)) { message = getMessageP("coiot.current-peer", MCMESSAGE, mcast ? "Multicast" : peer) + getMessageP("coiot.new-peer", MCINFO, displayPeer) + getMessageP(mcast ? "coiot.mode-peer" : "coiot.mode-mcast", MCMESSAGE); @@ -176,7 +176,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { refreshTimer = 20; break; case ACTION_RESET: - if (!update.equalsIgnoreCase("yes")) { + if (!"yes".equalsIgnoreCase(update)) { message = getMessageP("action.reset.warning", MCWARNING, serviceName); actionUrl = buildActionUrl(uid, action); } else { @@ -204,8 +204,8 @@ public class ShellyManagerActionPage extends ShellyManagerPage { break; case ACTION_ENDEBUG: case ACTION_DISDEBUG: - boolean enable = action.equalsIgnoreCase(ACTION_ENDEBUG); - if (!update.equalsIgnoreCase("yes")) { + boolean enable = ACTION_ENDEBUG.equalsIgnoreCase(action); + if (!"yes".equalsIgnoreCase(update)) { message = getMessage(enable ? "action.debug-enable" : "action.debug-disable"); actionUrl = buildActionUrl(uid, action); } else { @@ -222,7 +222,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { } break; case ACTION_RESSTA: - if (!update.equalsIgnoreCase("yes")) { + if (!"yes".equalsIgnoreCase(update)) { message = getMessage("action.resetsta-info"); actionUrl = buildActionUrl(uid, action); } else { @@ -237,8 +237,8 @@ public class ShellyManagerActionPage extends ShellyManagerPage { break; case ACTION_ENWIFIREC: case ACTION_DISWIFIREC: - enable = action.equalsIgnoreCase(ACTION_ENWIFIREC); - if (!update.equalsIgnoreCase("yes")) { + enable = ACTION_ENWIFIREC.equalsIgnoreCase(action); + if (!"yes".equalsIgnoreCase(update)) { message = getMessage(enable ? "action.setwifirec-enable" : "action.setwifirec-disable"); actionUrl = buildActionUrl(uid, action); } else { @@ -254,8 +254,8 @@ public class ShellyManagerActionPage extends ShellyManagerPage { case ACTION_ENAPROAMING: case ACTION_DISAPROAMING: - enable = action.equalsIgnoreCase(ACTION_ENAPROAMING); - if (!update.equalsIgnoreCase("yes")) { + enable = ACTION_ENAPROAMING.equalsIgnoreCase(action); + if (!"yes".equalsIgnoreCase(update)) { message = getMessage(enable ? "action.aproaming-enable" : "action.aproaming-disable"); actionUrl = buildActionUrl(uid, action); } else { @@ -272,7 +272,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { case ACTION_GETDEB: case ACTION_GETDEB1: try { - message = api.getDebugLog(action.equalsIgnoreCase(ACTION_GETDEB) ? "log" : "log1"); + message = api.getDebugLog(ACTION_GETDEB.equalsIgnoreCase(action) ? "log" : "log1"); message = message.replaceAll("[\r]", "").replaceAll("[\r\n]", "
"); } catch (ShellyApiException e) { message = getMessage("action.getdebug-failed", e.toString()); @@ -308,7 +308,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { if ((profile.settings.coiot != null) && (profile.settings.coiot.peer != null) && !profile.isMotion) { boolean mcast = profile.settings.coiot.peer.isEmpty() - || profile.settings.coiot.peer.equalsIgnoreCase(SHELLY_COIOT_MCAST); + || SHELLY_COIOT_MCAST.equalsIgnoreCase(profile.settings.coiot.peer); list.put(mcast ? ACTION_SETCOIOT_PEER : ACTION_SETCOIOT_MCAST, mcast ? "Set CoIoT Peer Mode" : "Set CoIoT Multicast Mode"); } @@ -332,7 +332,7 @@ public class ShellyManagerActionPage extends ShellyManagerPage { list.put(ACTION_RESET, "-Factory Reset"); if (profile.extFeatures) { list.put(ACTION_OTACHECK, "Check for Update"); - boolean debug_enable = getBool(profile.settings.debug_enable); + boolean debug_enable = getBool(profile.settings.debugEnable); list.put(!debug_enable ? ACTION_ENDEBUG : ACTION_DISDEBUG, !debug_enable ? "Enable Debug" : "Disable Debug"); if (debug_enable) { diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java index 8ba73b023..8a0d8da25 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerOtaPage.java @@ -115,7 +115,7 @@ public class ShellyManagerOtaPage extends ShellyManagerPage { properties.put(ATTRIBUTE_UPDATE_URL, "http://" + getDeviceIp(properties) + "/ota?" + updateUrl); properties.put(URLPARM_CONNECTION, connection); - if (update.equalsIgnoreCase("yes")) { + if ("yes".equalsIgnoreCase(update)) { // do the update th.setThingOffline(ThingStatusDetail.FIRMWARE_UPDATING, "offline.status-error-fwupgrade"); html += loadHTML(FWUPDATE2_HTML, properties); @@ -199,9 +199,9 @@ public class ShellyManagerOtaPage extends ShellyManagerPage { } else { // convert prod/beta to full url FwRepoEntry fw = getFirmwareRepoEntry(deviceType, mode); - String url = getString(prod ? fw.url : fw.beta_url); - logger.debug("ShellyManager: Map {} release to url {}, version {}", url, - prod ? fw.url : fw.beta_url, prod ? fw.version : fw.beta_ver); + String url = getString(prod ? fw.url : fw.betaUrl); + logger.debug("ShellyManager: Map {} release to url {}, version {}", url, prod ? fw.url : fw.betaUrl, + prod ? fw.version : fw.betaVer); return url; } default: // Update from firmware archive 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 b7932602c..bdadcf212 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 @@ -148,7 +148,7 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage { html += "\t\t\t\t\t\n"; } - bVersion = extractFwVersion(fw.beta_ver); + bVersion = extractFwVersion(fw.betaVer); if (!bVersion.isEmpty()) { html += "\t\t\t\t\t\n"; diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java index cbe79cb79..772ffd98d 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerPage.java @@ -63,6 +63,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; /** * {@link ShellyManagerOtaPage} implements the Shelly Manager's page template @@ -136,8 +137,10 @@ public class ShellyManagerPage { public @Nullable String url; // prod public @Nullable String version; - public @Nullable String beta_url; // beta version if avilable - public @Nullable String beta_ver; + @SerializedName("beta_url") + public @Nullable String betaUrl; // beta version if avilable + @SerializedName("beta_ver") + public @Nullable String betaVer; } public ShellyManagerPage(ConfigurationAdmin configurationAdmin, ShellyTranslationProvider translationProvider, @@ -242,7 +245,7 @@ public class ShellyManagerPage { addAttribute(properties, th, CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ALARM); addAttribute(properties, th, CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_CHARGER); - properties.put(ATTRIBUTE_DEBUG_MODE, getOption(profile.settings.debug_enable)); + properties.put(ATTRIBUTE_DEBUG_MODE, getOption(profile.settings.debugEnable)); properties.put(ATTRIBUTE_DISCOVERABLE, String.valueOf(getBool(profile.settings.discoverable))); properties.put(ATTRIBUTE_WIFI_RECOVERY, String.valueOf(getBool(profile.settings.wifiRecoveryReboot))); properties.put(ATTRIBUTE_APR_MODE, @@ -414,9 +417,9 @@ public class ShellyManagerPage { fw.url = url; logger.debug("ShellyManager: Release Split-URL for device type {} is {}", deviceType, url); } - url = substringBefore(fw.beta_url, ".zip") + "-" + mode + ".zip"; + url = substringBefore(fw.betaUrl, ".zip") + "-" + mode + ".zip"; if (testUrl(url)) { - fw.beta_url = url; + fw.betaUrl = url; logger.debug("ShellyManager: Beta Split-URL for device type {} is {}", deviceType, url); } } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java index d6083cd1d..66aa8d09b 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/manager/ShellyManagerServlet.java @@ -125,9 +125,11 @@ public class ShellyManagerServlet extends HttpServlet { } else { // binary data byte[] data = (byte[]) output.data; - response.setContentLength(data.length); - bin = response.getOutputStream(); - bin.write(data, 0, data.length); + if (data != null) { + response.setContentLength(data.length); + bin = response.getOutputStream(); + bin.write(data, 0, data.length); + } } } catch (ShellyApiException | RuntimeException e) { logger.debug("{}: Exception uri={}, parameters={}", className, path, request.getParameterMap().toString(), 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 e3e4308a3..50f21cbd2 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 @@ -175,7 +175,6 @@ public class ShellyChannelDefinitions { .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VOLTAGE, "sensorADC", ITEMT_VOLT)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_CONTACT, "sensorContact", ITEMT_CONTACT)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_SSTATE, "sensorState", ITEMT_STRING)) - .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VIBRATION, "sensorVibration", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TILT, "sensorTilt", ITEMT_ANGLE)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION, "sensorMotion", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION_TS, "motionTimestamp", ITEMT_DATETIME)) @@ -424,8 +423,6 @@ public class ShellyChannelDefinitions { CHANNEL_SENSOR_VIBRATION); } if (sdata.accel != null) { // DW2 - addChannel(thing, newChannels, sdata.accel.vibration != null, CHANNEL_GROUP_SENSOR, - CHANNEL_SENSOR_VIBRATION); addChannel(thing, newChannels, sdata.accel.tilt != null, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_TILT); } @@ -564,18 +561,17 @@ public class ShellyChannelDefinitions { public String getGroupAttribute(String attribute) { String key = PREFIX_GROUP + group + "." + attribute; String value = messages.getText(key); - return value != null && !value.equals(key) ? value : ""; + return !value.equals(key) ? value : ""; } public String getChannelAttribute(String attribute) { String key = PREFIX_CHANNEL + channel + "." + attribute; String value = messages.getText(key); - return value != null && !value.equals(key) ? value : ""; + return !value.equals(key) ? value : ""; } private String getText(String key) { - String text = messages.get(key); - return text != null ? text : ""; + return messages.get(key); } } diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java index 749e36f74..d37b4a4ee 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/util/ShellyUtils.java @@ -52,8 +52,8 @@ import com.google.gson.JsonSyntaxException; */ @NonNullByDefault public class ShellyUtils { - private final static String PRE = "Unable to create object of type "; - public final static DateTimeFormatter DATE_TIME = DateTimeFormatter.ofPattern(DateTimeType.DATE_PATTERN); + private static final String PRE = "Unable to create object of type "; + public static final DateTimeFormatter DATE_TIME = DateTimeFormatter.ofPattern(DateTimeType.DATE_PATTERN); public static T fromJson(Gson gson, @Nullable String json, Class classOfT) throws ShellyApiException { @Nullable @@ -96,6 +96,7 @@ public class ShellyUtils { } } + @SuppressWarnings("unchecked") private static Class wrap(Class type) { if (type == int.class) { return (Class) Integer.class;