mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 23:22:02 +01:00
[homematic] Fix long button press handling for HM-IP devices (#11982)
* [homematic] Fix long button press handling for HM-IP devices HM devices have the following long press cycle: PRESS_CONT PRESS_LONG PRESS_CONT (N times for repetion) PRESS_LONG_RELEASE while (at least some) HM-IP devices use this one: PRESS_LONG PRESS_LONG_START PRESS_LONG (N times for repetition) PRESS_LONG_RELEASE Add support for the latter case while keeping support for the former case. Signed-off-by: Danny Baumann <dannybaumann@web.de> * [homematic] Track 'uses LONG_START datapoint' flag per-device
This commit is contained in:
parent
a1e6a4e35c
commit
a4c579b753
@ -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 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.misc.MiscUtils;
|
||||||
import org.openhab.binding.homematic.internal.model.HmChannel;
|
import org.openhab.binding.homematic.internal.model.HmChannel;
|
||||||
import org.openhab.binding.homematic.internal.model.HmDatapoint;
|
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_REPEATED_EVENT = "LONG_REPEATED";
|
||||||
private static final String LONG_RELEASED_EVENT = "LONG_RELEASED";
|
private static final String LONG_RELEASED_EVENT = "LONG_RELEASED";
|
||||||
|
|
||||||
|
private HashSet<String> devicesUsingLongStartEvent = new HashSet<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return VIRTUAL_DATAPOINT_NAME_BUTTON;
|
return VIRTUAL_DATAPOINT_NAME_BUTTON;
|
||||||
@ -61,6 +65,7 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl
|
|||||||
@Override
|
@Override
|
||||||
public void handleEvent(VirtualGateway gateway, HmDatapoint dp) {
|
public void handleEvent(VirtualGateway gateway, HmDatapoint dp) {
|
||||||
HmChannel channel = dp.getChannel();
|
HmChannel channel = dp.getChannel();
|
||||||
|
String deviceSerial = channel.getDevice().getAddress();
|
||||||
HmDatapoint vdp = getVirtualDatapoint(channel);
|
HmDatapoint vdp = getVirtualDatapoint(channel);
|
||||||
int usPos = dp.getName().indexOf("_");
|
int usPos = dp.getName().indexOf("_");
|
||||||
String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1);
|
String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1);
|
||||||
@ -74,13 +79,20 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "LONG":
|
case "LONG":
|
||||||
if (LONG_REPEATED_EVENT.equals(vdp.getValue())) {
|
if (isLongPressActive) {
|
||||||
// Suppress long press events during an ongoing long press
|
// 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);
|
vdp.setValue(LONG_REPEATED_EVENT);
|
||||||
} else {
|
} else {
|
||||||
|
// HM devices start long press via LONG events
|
||||||
vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
|
vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "LONG_START":
|
||||||
|
vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
|
||||||
|
devicesUsingLongStartEvent.add(deviceSerial);
|
||||||
|
break;
|
||||||
case "LONG_RELEASE":
|
case "LONG_RELEASE":
|
||||||
// Only send release events if we sent a pressed event before
|
// Only send release events if we sent a pressed event before
|
||||||
vdp.setValue(isLongPressActive ? LONG_RELEASED_EVENT : null);
|
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);
|
logger.warn("Unexpected vaule '{}' for PRESS virtual datapoint", pressType);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// 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
|
// event time out the repetitions, the CONT delay handler will take care of it
|
||||||
vdp.setValue(LONG_REPEATED_EVENT);
|
vdp.setValue(LONG_REPEATED_EVENT);
|
||||||
|
@ -60,7 +60,7 @@ public class ButtonDatapointTest extends JavaTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongPress() throws IOException, HomematicClientException {
|
public void testLongPressHm() throws IOException, HomematicClientException {
|
||||||
HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG", Boolean.TRUE);
|
HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG", Boolean.TRUE);
|
||||||
HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
|
HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
|
||||||
|
|
||||||
@ -76,6 +76,23 @@ public class ButtonDatapointTest extends JavaTest {
|
|||||||
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
|
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
|
@Test
|
||||||
public void testUnsupportedEvents() throws IOException, HomematicClientException {
|
public void testUnsupportedEvents() throws IOException, HomematicClientException {
|
||||||
HmDatapoint contPressDp = createPressDatapoint("PRESS_CONT", Boolean.TRUE);
|
HmDatapoint contPressDp = createPressDatapoint("PRESS_CONT", Boolean.TRUE);
|
||||||
|
Loading…
Reference in New Issue
Block a user