diff --git a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java index f3f58e83393..03e6019f66d 100644 --- a/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java +++ b/bundles/org.openhab.binding.homematic/src/main/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonVirtualDatapointHandler.java @@ -14,6 +14,8 @@ package org.openhab.binding.homematic.internal.communicator.virtual; import static org.openhab.binding.homematic.internal.misc.HomematicConstants.VIRTUAL_DATAPOINT_NAME_BUTTON; +import java.util.HashSet; + import org.openhab.binding.homematic.internal.misc.MiscUtils; import org.openhab.binding.homematic.internal.model.HmChannel; import org.openhab.binding.homematic.internal.model.HmDatapoint; @@ -36,6 +38,8 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl private static final String LONG_REPEATED_EVENT = "LONG_REPEATED"; private static final String LONG_RELEASED_EVENT = "LONG_RELEASED"; + private HashSet devicesUsingLongStartEvent = new HashSet<>(); + @Override public String getName() { return VIRTUAL_DATAPOINT_NAME_BUTTON; @@ -61,6 +65,7 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl @Override public void handleEvent(VirtualGateway gateway, HmDatapoint dp) { HmChannel channel = dp.getChannel(); + String deviceSerial = channel.getDevice().getAddress(); HmDatapoint vdp = getVirtualDatapoint(channel); int usPos = dp.getName().indexOf("_"); String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1); @@ -74,13 +79,20 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl break; } case "LONG": - if (LONG_REPEATED_EVENT.equals(vdp.getValue())) { - // Suppress long press events during an ongoing long press + if (isLongPressActive) { + // HM-IP devices do long press repetitions via LONG instead of CONT events, + // so clear previous value to force re-triggering of event + vdp.setValue(null); vdp.setValue(LONG_REPEATED_EVENT); } else { + // HM devices start long press via LONG events vdp.setValue(CommonTriggerEvents.LONG_PRESSED); } break; + case "LONG_START": + vdp.setValue(CommonTriggerEvents.LONG_PRESSED); + devicesUsingLongStartEvent.add(deviceSerial); + break; case "LONG_RELEASE": // Only send release events if we sent a pressed event before vdp.setValue(isLongPressActive ? LONG_RELEASED_EVENT : null); @@ -99,7 +111,8 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl logger.warn("Unexpected vaule '{}' for PRESS virtual datapoint", pressType); } } else { - if ("LONG".equals(pressType) && LONG_REPEATED_EVENT.equals(vdp.getValue())) { + String usedStartEvent = devicesUsingLongStartEvent.contains(deviceSerial) ? "LONG_START" : "LONG"; + if (usedStartEvent.equals(pressType) && LONG_REPEATED_EVENT.equals(vdp.getValue())) { // If we're currently processing a repeated long-press event, don't let the initial LONG // event time out the repetitions, the CONT delay handler will take care of it vdp.setValue(LONG_REPEATED_EVENT); diff --git a/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java b/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java index a22cfbb20a8..02b6bdeeb39 100644 --- a/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java +++ b/bundles/org.openhab.binding.homematic/src/test/java/org/openhab/binding/homematic/internal/communicator/virtual/ButtonDatapointTest.java @@ -60,7 +60,7 @@ public class ButtonDatapointTest extends JavaTest { } @Test - public void testLongPress() throws IOException, HomematicClientException { + public void testLongPressHm() throws IOException, HomematicClientException { HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG", Boolean.TRUE); HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp); @@ -76,6 +76,23 @@ public class ButtonDatapointTest extends JavaTest { assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED")); } + @Test + public void testLongPressHmIp() throws IOException, HomematicClientException { + HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG_START", Boolean.TRUE); + HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp); + + mockEventReceiver.eventReceived(longPressDp); + assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED)); + + HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE); + mockEventReceiver.eventReceived(contPressDp); + assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED")); + + HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE); + mockEventReceiver.eventReceived(releaseDp); + assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED")); + } + @Test public void testUnsupportedEvents() throws IOException, HomematicClientException { HmDatapoint contPressDp = createPressDatapoint("PRESS_CONT", Boolean.TRUE);