From f9374d8b516753c606613c483247e1a032867800 Mon Sep 17 00:00:00 2001 From: Markus Michels Date: Fri, 8 May 2020 08:03:26 +0200 Subject: [PATCH] [shelly] Bug fixes (#7563) * Code base for PR 6335 based on 2.5.2-SNAPSHOT * org.openhab.binding.magentatv added as module * adapted to 2.5.4 * applying review comments - WIP * changes WIP * Changed the default of autoCoIoT to true in the Java class. This is important when an existing installation is updated. Otherwise the properties are loaded, autoCoIoT is not included and default was false. * improved handling of short/longpush on CoAP updates; roller action urls are not enforced on autoCoIoT * #7558: Fixed short/long pressed events when reported by CoAP * #7560: Resolve fqdn into IP address * clean out files * cleanout magentatv * typo fixed Signed-off-by: Markus Michels --- bundles/org.openhab.binding.shelly/README.md | 1 + .../internal/ShellyBindingConstants.java | 2 +- .../shelly/internal/api/ShellyApiJsonDTO.java | 1 + .../internal/coap/ShellyCoapHandler.java | 78 +++++++++++-------- .../config/ShellyBindingConfiguration.java | 5 +- .../internal/handler/ShellyBaseHandler.java | 20 ++++- 6 files changed, 73 insertions(+), 34 deletions(-) diff --git a/bundles/org.openhab.binding.shelly/README.md b/bundles/org.openhab.binding.shelly/README.md index ae8bf1d70136..5e247257c997 100644 --- a/bundles/org.openhab.binding.shelly/README.md +++ b/bundles/org.openhab.binding.shelly/README.md @@ -474,6 +474,7 @@ The binding emulates this by using the system time on every update. In white mode each RGBW2 channel is defined as DimmableLight. This means that the brightness channel has 2 functions + - Sending ON/OFF (OnOffType) to power on/off the channel - Sending a Number to set the brightness (percentage 0..100) 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 0b26ea2e2afe..fd8f0de6af4f 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 @@ -50,7 +50,7 @@ public class ShellyBindingConstants { public static final String THING_TYPE_SHELLYDIMMER_STR = "shellydimmer"; public static final String THING_TYPE_SHELLYBULB_STR = "shellybulb"; public static final String THING_TYPE_SHELLYDUO_STR = "shellybulbduo"; - public static final String THING_TYPE_SHELLYVINTAGE_STR = "shellybulbvintage"; + public static final String THING_TYPE_SHELLYVINTAGE_STR = "shellyvintage"; public static final String THING_TYPE_SHELLYRGBW2_PREFIX = "shellyrgbw2"; public static final String THING_TYPE_SHELLYRGBW2_COLOR_STR = "shellyrgbw2-color"; public static final String THING_TYPE_SHELLYRGBW2_WHITE_STR = "shellyrgbw2-white"; 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 8a591ac14d8c..9c9a16dc5d0b 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 @@ -91,6 +91,7 @@ public class ShellyApiJsonDTO { // API values // public static final String SHELLY_BTNT_MOMENTARY = "momentary"; + public static final String SHELLY_BTNT_MOM_ON_RELEASE = "momentary_on_release"; public static final String SHELLY_BTNT_TOGGLE = "toggle"; public static final String SHELLY_BTNT_EDGE = "edge"; public static final String SHELLY_BTNT_DETACHED = "detached"; 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 a84416c968f3..300bae587126 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 @@ -484,37 +484,7 @@ private void handleStatusUpdate(String devId, String payload, int serial) { toQuantityType(pos, SmartHomeUnits.PERCENT)); break; case "input": - int idx = getSensorNumber("Input", sen.id); - if (idx > 0) { - int r = idx - 1; - String iGroup = rGroup; - String iChannel = CHANNEL_INPUT; - if (profile.isRGBW2) { - // RGBW2 has only one input, not one per channel - iGroup = CHANNEL_GROUP_LIGHT_CONTROL; - } else if (profile.isDimmer || profile.isRoller) { - // Dimmer and Roller things have 2 inputs - iChannel = CHANNEL_INPUT + String.valueOf(idx); - } else { - // Device has 1 input per relay: 0=off, 1+2 depend on switch mode - iGroup = profile.numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL - : CHANNEL_GROUP_RELAY_CONTROL + idx; - } - - if ((profile.settings.relays != null) && (r >= 0) - && (r < profile.settings.relays.size())) { - ShellySettingsRelay relay = profile.settings.relays.get(r); - if ((relay != null) && (s.value != 0) - && (relay.btnType.equalsIgnoreCase(SHELLY_BTNT_MOMENTARY) - || relay.btnType.equalsIgnoreCase(SHELLY_BTNT_DETACHED))) { - updateChannel(updates, iGroup, CHANNEL_BUTTON_TRIGGER, - getStringType(s.value == 1 ? CommonTriggerEvents.SHORT_PRESSED - : CommonTriggerEvents.LONG_PRESSED)); - } - } - updateChannel(updates, iGroup, iChannel, - s.value == 0 ? OnOffType.OFF : OnOffType.ON); - } + handleInput(sen, s, rGroup, updates); break; case "flood": updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_FLOOD, @@ -606,6 +576,52 @@ private void handleStatusUpdate(String devId, String payload, int serial) { lastPayload = payload; } + private void handleInput(CoIotDescrSen sen, CoIotSensor s, String rGroup, Map updates) { + final ShellyDeviceProfile profile = thingHandler.getProfile(); + int idx = getSensorNumber("Input", sen.id); + if (idx > 0) { + int r = idx - 1; + String iGroup = rGroup; + String iChannel = CHANNEL_INPUT; + if (profile.isRGBW2) { + // RGBW2 has only one input, not one per channel + iGroup = CHANNEL_GROUP_LIGHT_CONTROL; + } else if (profile.isDimmer || profile.isRoller) { + // Dimmer and Roller things have 2 inputs + iChannel = CHANNEL_INPUT + String.valueOf(idx); + } else { + // Device has 1 input per relay: 0=off, 1+2 depend on switch mode + iGroup = profile.numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL : CHANNEL_GROUP_RELAY_CONTROL + idx; + } + + if ((profile.settings.relays != null) && (r >= 0) && (r < profile.settings.relays.size())) { + ShellySettingsRelay relay = profile.settings.relays.get(r); + logger.trace("{}: Coap update for button (type {})", thingName, relay.btnType); + if ((s.value != 0) && (relay.btnType.equalsIgnoreCase(SHELLY_BTNT_MOMENTARY) + || relay.btnType.equalsIgnoreCase(SHELLY_BTNT_MOM_ON_RELEASE) + || relay.btnType.equalsIgnoreCase(SHELLY_BTNT_DETACHED))) { + String trigger = ""; + switch (new Double(s.value).intValue()) { + case 0: + trigger = CommonTriggerEvents.RELEASED; + break; + case 1: + trigger = CommonTriggerEvents.SHORT_PRESSED; + break; + case 2: + trigger = CommonTriggerEvents.LONG_PRESSED; + break; + } + if (!trigger.isEmpty()) { + logger.debug("{}: Update button state with {}", thingName, trigger); + thingHandler.triggerChannel(iGroup, CHANNEL_BUTTON_TRIGGER, trigger); + } + } + } + updateChannel(updates, iGroup, iChannel, s.value == 0 ? OnOffType.OFF : OnOffType.ON); + } + } + /** * * Handles the combined updated of the brightness channel: diff --git a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/config/ShellyBindingConfiguration.java b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/config/ShellyBindingConfiguration.java index c3180806fc28..4007b43097a5 100644 --- a/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/config/ShellyBindingConfiguration.java +++ b/bundles/org.openhab.binding.shelly/src/main/java/org/openhab/binding/shelly/internal/config/ShellyBindingConfiguration.java @@ -35,10 +35,13 @@ public class ShellyBindingConfiguration { public String defaultUserId = ""; // default for http basic user id public String defaultPassword = ""; // default for http basic auth password - public boolean autoCoIoT = false; + public boolean autoCoIoT = true; public void updateFromProperties(Map properties) { for (Map.Entry e : properties.entrySet()) { + if (e.getValue() == null) { + continue; + } switch (e.getKey()) { case CONFIG_DEF_HTTP_USER: defaultUserId = (String) e.getValue(); 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 5a3a9c9ab599..950ffbaea12e 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 @@ -17,6 +17,8 @@ import static org.openhab.binding.shelly.internal.api.ShellyApiJsonDTO.*; import static org.openhab.binding.shelly.internal.util.ShellyUtils.*; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -257,11 +259,11 @@ private boolean initializeThing() throws ShellyApiException { config.eventsSwitch = false; config.eventsButton = false; config.eventsPush = false; - config.eventsRoller = true; // so far missing with FW 1.6+CoIoT config.eventsSensorReport = false; api.setConfig(thingName, config); } if (config.eventsCoIoT) { + logger.debug("{}: Starting CoIoT (autoCoIoT={}/{})", thingName, bindingConfig.autoCoIoT, autoCoIoT); coap.start(thingName, config); } @@ -630,6 +632,21 @@ protected void initializeThingConfig() { } config = getConfigAs(ShellyThingConfiguration.class); + if (config.deviceIp.isEmpty()) { + logger.info("{}: IP address for the device must not be empty", thingName); // may not set in .things file + return; + } + try { + InetAddress addr = InetAddress.getByName(config.deviceIp); + String saddr = addr.getHostAddress(); + if (!config.deviceIp.equals(saddr)) { + logger.debug("{}: hostname {} resolved to IP address {}", thingName, config.deviceIp, saddr); + config.deviceIp = saddr; + } + } catch (UnknownHostException e) { + logger.debug("{}: Unable to resolehostname {}", thingName, config.deviceIp); + } + config.localIp = localIP; config.localPort = localPort; if (config.userId.isEmpty() && !bindingConfig.defaultUserId.isEmpty()) { @@ -643,6 +660,7 @@ protected void initializeThingConfig() { if (config.updateInterval < UPDATE_MIN_DELAY) { config.updateInterval = UPDATE_MIN_DELAY; } + skipCount = config.updateInterval / UPDATE_STATUS_INTERVAL_SECONDS; }