2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.homematic.internal.communicator.virtual;
15 import static org.hamcrest.CoreMatchers.*;
16 import static org.hamcrest.MatcherAssert.assertThat;
18 import java.io.IOException;
20 import org.junit.jupiter.api.BeforeEach;
21 import org.junit.jupiter.api.Test;
22 import org.openhab.binding.homematic.internal.misc.HomematicClientException;
23 import org.openhab.binding.homematic.internal.misc.HomematicConstants;
24 import org.openhab.binding.homematic.internal.misc.MiscUtils;
25 import org.openhab.binding.homematic.internal.model.HmChannel;
26 import org.openhab.binding.homematic.internal.model.HmDatapoint;
27 import org.openhab.binding.homematic.internal.model.HmDevice;
28 import org.openhab.binding.homematic.internal.model.HmInterface;
29 import org.openhab.binding.homematic.internal.model.HmParamsetType;
30 import org.openhab.binding.homematic.internal.model.HmValueType;
31 import org.openhab.core.test.java.JavaTest;
32 import org.openhab.core.thing.CommonTriggerEvents;
35 * Tests for {@link ButtonVirtualDatapointHandler}.
37 * @author Michael Reitler - Initial Contribution
40 public class ButtonDatapointTest extends JavaTest {
42 private static final int DISABLE_DATAPOINT_DELAY = 50;
44 private MockEventReceiver mockEventReceiver;
45 private final ButtonVirtualDatapointHandler bvdpHandler = new ButtonVirtualDatapointHandler();
48 public void setup() throws IOException {
49 this.mockEventReceiver = new MockEventReceiver();
53 public void testShortPress() throws IOException, HomematicClientException {
54 HmDatapoint shortPressDp = createPressDatapoint("PRESS_SHORT", Boolean.TRUE);
55 HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(shortPressDp);
57 mockEventReceiver.eventReceived(shortPressDp);
59 assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.SHORT_PRESSED));
63 public void testLongPressHm() throws IOException, HomematicClientException {
64 HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG", Boolean.TRUE);
65 HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
67 mockEventReceiver.eventReceived(longPressDp);
68 assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED));
70 HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
71 mockEventReceiver.eventReceived(contPressDp);
72 assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
74 HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
75 mockEventReceiver.eventReceived(releaseDp);
76 assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
80 public void testLongPressHmIp() throws IOException, HomematicClientException {
81 HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG_START", Boolean.TRUE);
82 HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
84 mockEventReceiver.eventReceived(longPressDp);
85 assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED));
87 HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE);
88 mockEventReceiver.eventReceived(contPressDp);
89 assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
91 HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
92 mockEventReceiver.eventReceived(releaseDp);
93 assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
97 public void testUnsupportedEvents() throws IOException, HomematicClientException {
98 HmDatapoint contPressDp = createPressDatapoint("PRESS_CONT", Boolean.TRUE);
99 HmDatapoint contButtonVirtualDatapoint = getButtonVirtualDatapoint(contPressDp);
101 mockEventReceiver.eventReceived(contPressDp);
103 HmDatapoint releaseDp = createPressDatapoint("PRESS_LONG_RELEASE", Boolean.TRUE);
104 HmDatapoint releaseButtonVirtualDatapoint = getButtonVirtualDatapoint(releaseDp);
106 mockEventReceiver.eventReceived(releaseDp);
108 HmDatapoint crapDp = createPressDatapoint("CRAP", Boolean.TRUE);
109 HmDatapoint crapButtonVirtualDatapoint = getButtonVirtualDatapoint(crapDp);
111 mockEventReceiver.eventReceived(crapDp);
113 // CONT and LONG_RELEASE events without previous LONG event are supposed to yield no trigger
114 assertThat(contButtonVirtualDatapoint.getValue(), nullValue());
115 assertThat(releaseButtonVirtualDatapoint.getValue(), nullValue());
116 assertThat(crapButtonVirtualDatapoint, nullValue());
119 private HmDatapoint createPressDatapoint(String channelName, Object value) {
120 HmDatapoint pressDp = new HmDatapoint(channelName, "", HmValueType.ACTION, value, true, HmParamsetType.VALUES);
121 HmChannel hmChannel = new HmChannel(channelName, 1);
122 HmDevice device = new HmDevice("ABC12345", HmInterface.RF, "HM-MOCK", "mockid", "mockid", "mockfw");
123 hmChannel.setDevice(device);
124 device.addChannel(hmChannel);
125 hmChannel.addDatapoint(pressDp);
126 pressDp.setChannel(hmChannel);
127 bvdpHandler.initialize(device);
132 private HmDatapoint createPressDatapointFrom(HmDatapoint originalDatapoint, String channelName, Object value) {
133 HmDatapoint pressDp = new HmDatapoint(channelName, "", HmValueType.ACTION, value, true, HmParamsetType.VALUES);
134 HmChannel hmChannel = originalDatapoint.getChannel();
135 hmChannel.addDatapoint(pressDp);
136 pressDp.setChannel(hmChannel);
141 private HmDatapoint getButtonVirtualDatapoint(HmDatapoint originalDatapoint) {
142 return originalDatapoint.getChannel().getDatapoints().stream()
143 .filter(dp -> HomematicConstants.VIRTUAL_DATAPOINT_NAME_BUTTON.equals(dp.getName())).findFirst()
148 * Mock parts of {@linkplain org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway}
150 private class MockEventReceiver {
152 public void eventReceived(HmDatapoint dp) throws IOException, HomematicClientException {
153 if (bvdpHandler.canHandleEvent(dp)) {
154 bvdpHandler.handleEvent(null, dp);
156 if (dp.isPressDatapoint() && MiscUtils.isTrueValue(dp.getValue())) {
157 disableDatapoint(dp);
161 private void disableDatapoint(HmDatapoint dp) {
164 Thread.sleep(DISABLE_DATAPOINT_DELAY);
165 dp.setValue(Boolean.FALSE);
166 } catch (InterruptedException e) {