HmDatapoint vdp = getVirtualDatapoint(channel);
int usPos = dp.getName().indexOf("_");
String pressType = usPos == -1 ? dp.getName() : dp.getName().substring(usPos + 1);
+ boolean usesLongStart = devicesUsingLongStartEvent.contains(deviceSerial);
boolean isLongPressActive = CommonTriggerEvents.LONG_PRESSED.equals(vdp.getValue())
|| LONG_REPEATED_EVENT.equals(vdp.getValue());
if (MiscUtils.isTrueValue(dp.getValue())) {
break;
}
case "LONG":
- if (isLongPressActive) {
+ if (usesLongStart) {
// 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);
+ if (isLongPressActive) {
+ vdp.setValue(null);
+ vdp.setValue(LONG_REPEATED_EVENT);
+ }
} else {
- // HM devices start long press via LONG events
- vdp.setValue(CommonTriggerEvents.LONG_PRESSED);
+ // HM devices start long press via LONG events, but also may keep sending them
+ // 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;
case "LONG_START":
break;
default:
vdp.setValue(null);
- logger.warn("Unexpected vaule '{}' for PRESS virtual datapoint", pressType);
+ logger.warn("Unexpected value '{}' for PRESS virtual datapoint", pressType);
}
} 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 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
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
mockEventReceiver.eventReceived(contPressDp);
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);
mockEventReceiver.eventReceived(releaseDp);
HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE);
mockEventReceiver.eventReceived(contPressDp);
assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
+ assertThat(buttonVirtualDatapoint.getPreviousValue(), nullValue());
HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
mockEventReceiver.eventReceived(releaseDp);