mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[homematic] Fix duplication of LONG_REPEATED events for HM devices (#15906)
Depending on device configuration and used central [1], HM devices may indicate long press repetition either by a single PRESS_CONT event or by a PRESS_CONT + PRESS_LONG combination. In the latter case, make sure to not generate a LONG_REPEATED trigger channel event for both PRESS_CONT and PRESS_LONG, but instead keep LONG_REPEATED generation to the PRESS_CONT handling. [1] I'm not sure what a real CCU is doing, but for Homegear, a configured long press timeout of less than 1s generates only PRESS_CONT, while a timeout of more than 1s generates PRESS_CONT + PRESS_LONG ... see [2]. [2] https://github.com/Homegear/Homegear-HomeMaticBidCoS/blob/master/src/BidCoSPeer.cpp#L1711-L1716 Signed-off-by: Danny Baumann <dannybaumann@web.de>
This commit is contained in:
parent
01ab38ee13
commit
87ae9e2a37
@ -68,6 +68,7 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl
|
|||||||
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);
|
||||||
|
boolean usesLongStart = devicesUsingLongStartEvent.contains(deviceSerial);
|
||||||
boolean isLongPressActive = CommonTriggerEvents.LONG_PRESSED.equals(vdp.getValue())
|
boolean isLongPressActive = CommonTriggerEvents.LONG_PRESSED.equals(vdp.getValue())
|
||||||
|| LONG_REPEATED_EVENT.equals(vdp.getValue());
|
|| LONG_REPEATED_EVENT.equals(vdp.getValue());
|
||||||
if (MiscUtils.isTrueValue(dp.getValue())) {
|
if (MiscUtils.isTrueValue(dp.getValue())) {
|
||||||
@ -78,14 +79,18 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "LONG":
|
case "LONG":
|
||||||
if (isLongPressActive) {
|
if (usesLongStart) {
|
||||||
// HM-IP devices do long press repetitions via LONG instead of CONT events,
|
// HM-IP devices do long press repetitions via LONG instead of CONT events,
|
||||||
// so clear previous value to force re-triggering of event
|
// so clear previous value to force re-triggering of event
|
||||||
vdp.setValue(null);
|
if (isLongPressActive) {
|
||||||
vdp.setValue(LONG_REPEATED_EVENT);
|
vdp.setValue(null);
|
||||||
|
vdp.setValue(LONG_REPEATED_EVENT);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// HM devices start long press via LONG events
|
// HM devices start long press via LONG events, but also may keep sending them
|
||||||
vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
|
// alongside CONT repetition events. In case a long press is already active, we just
|
||||||
|
// acknowledge those events by setting the value again, to make sure to not re-trigger events
|
||||||
|
vdp.setValue(isLongPressActive ? LONG_REPEATED_EVENT : CommonTriggerEvents.LONG_PRESSED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "LONG_START":
|
case "LONG_START":
|
||||||
@ -107,10 +112,10 @@ public class ButtonVirtualDatapointHandler extends AbstractVirtualDatapointHandl
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vdp.setValue(null);
|
vdp.setValue(null);
|
||||||
logger.warn("Unexpected vaule '{}' for PRESS virtual datapoint", pressType);
|
logger.warn("Unexpected value '{}' for PRESS virtual datapoint", pressType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String usedStartEvent = devicesUsingLongStartEvent.contains(deviceSerial) ? "LONG_START" : "LONG";
|
String usedStartEvent = usesLongStart ? "LONG_START" : "LONG";
|
||||||
if (usedStartEvent.equals(pressType) && LONG_REPEATED_EVENT.equals(vdp.getValue())) {
|
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
|
||||||
|
@ -70,6 +70,12 @@ public class ButtonDatapointTest extends JavaTest {
|
|||||||
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
|
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
|
||||||
mockEventReceiver.eventReceived(contPressDp);
|
mockEventReceiver.eventReceived(contPressDp);
|
||||||
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
|
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
|
||||||
|
assertThat(buttonVirtualDatapoint.getPreviousValue(), nullValue());
|
||||||
|
|
||||||
|
// Receiving another LONG event during the long press should be ignored
|
||||||
|
mockEventReceiver.eventReceived(longPressDp);
|
||||||
|
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
|
||||||
|
assertThat(buttonVirtualDatapoint.getPreviousValue(), is("LONG_REPEATED"));
|
||||||
|
|
||||||
HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
|
HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
|
||||||
mockEventReceiver.eventReceived(releaseDp);
|
mockEventReceiver.eventReceived(releaseDp);
|
||||||
@ -87,6 +93,7 @@ public class ButtonDatapointTest extends JavaTest {
|
|||||||
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE);
|
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE);
|
||||||
mockEventReceiver.eventReceived(contPressDp);
|
mockEventReceiver.eventReceived(contPressDp);
|
||||||
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
|
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
|
||||||
|
assertThat(buttonVirtualDatapoint.getPreviousValue(), nullValue());
|
||||||
|
|
||||||
HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
|
HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
|
||||||
mockEventReceiver.eventReceived(releaseDp);
|
mockEventReceiver.eventReceived(releaseDp);
|
||||||
|
Loading…
Reference in New Issue
Block a user