]> git.basschouten.com Git - openhab-addons.git/blob
dc49e38781bf7c6da681d335a20d43610dc43529
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.homematic.internal.communicator.virtual;
14
15 import static org.hamcrest.CoreMatchers.*;
16 import static org.hamcrest.MatcherAssert.assertThat;
17
18 import java.io.IOException;
19
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;
33
34 /**
35  * Tests for {@link ButtonVirtualDatapointHandler}.
36  *
37  * @author Michael Reitler - Initial Contribution
38  *
39  */
40 public class ButtonDatapointTest extends JavaTest {
41
42     private static final int DISABLE_DATAPOINT_DELAY = 50;
43
44     private MockEventReceiver mockEventReceiver;
45     private final ButtonVirtualDatapointHandler bvdpHandler = new ButtonVirtualDatapointHandler();
46
47     @BeforeEach
48     public void setup() throws IOException {
49         this.mockEventReceiver = new MockEventReceiver();
50     }
51
52     @Test
53     public void testShortPress() throws IOException, HomematicClientException {
54         HmDatapoint shortPressDp = createPressDatapoint("PRESS_SHORT", Boolean.TRUE);
55         HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(shortPressDp);
56
57         mockEventReceiver.eventReceived(shortPressDp);
58
59         assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.SHORT_PRESSED));
60     }
61
62     @Test
63     public void testLongPressHm() throws IOException, HomematicClientException {
64         HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG", Boolean.TRUE);
65         HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
66
67         mockEventReceiver.eventReceived(longPressDp);
68         assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED));
69
70         HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_CONT", Boolean.TRUE);
71         mockEventReceiver.eventReceived(contPressDp);
72         assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
73         assertThat(buttonVirtualDatapoint.getPreviousValue(), nullValue());
74
75         // Receiving another LONG event during the long press should be ignored
76         mockEventReceiver.eventReceived(longPressDp);
77         assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
78         assertThat(buttonVirtualDatapoint.getPreviousValue(), is("LONG_REPEATED"));
79
80         HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
81         mockEventReceiver.eventReceived(releaseDp);
82         assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
83     }
84
85     @Test
86     public void testLongPressHmIp() throws IOException, HomematicClientException {
87         HmDatapoint longPressDp = createPressDatapoint("PRESS_LONG_START", Boolean.TRUE);
88         HmDatapoint buttonVirtualDatapoint = getButtonVirtualDatapoint(longPressDp);
89
90         mockEventReceiver.eventReceived(longPressDp);
91         assertThat(buttonVirtualDatapoint.getValue(), is(CommonTriggerEvents.LONG_PRESSED));
92
93         HmDatapoint contPressDp = createPressDatapointFrom(longPressDp, "PRESS_LONG", Boolean.TRUE);
94         mockEventReceiver.eventReceived(contPressDp);
95         assertThat(buttonVirtualDatapoint.getValue(), is("LONG_REPEATED"));
96         assertThat(buttonVirtualDatapoint.getPreviousValue(), nullValue());
97
98         HmDatapoint releaseDp = createPressDatapointFrom(longPressDp, "PRESS_LONG_RELEASE", Boolean.TRUE);
99         mockEventReceiver.eventReceived(releaseDp);
100         assertThat(buttonVirtualDatapoint.getValue(), is("LONG_RELEASED"));
101     }
102
103     @Test
104     public void testUnsupportedEvents() throws IOException, HomematicClientException {
105         HmDatapoint contPressDp = createPressDatapoint("PRESS_CONT", Boolean.TRUE);
106         HmDatapoint contButtonVirtualDatapoint = getButtonVirtualDatapoint(contPressDp);
107
108         mockEventReceiver.eventReceived(contPressDp);
109
110         HmDatapoint releaseDp = createPressDatapoint("PRESS_LONG_RELEASE", Boolean.TRUE);
111         HmDatapoint releaseButtonVirtualDatapoint = getButtonVirtualDatapoint(releaseDp);
112
113         mockEventReceiver.eventReceived(releaseDp);
114
115         HmDatapoint crapDp = createPressDatapoint("CRAP", Boolean.TRUE);
116         HmDatapoint crapButtonVirtualDatapoint = getButtonVirtualDatapoint(crapDp);
117
118         mockEventReceiver.eventReceived(crapDp);
119
120         // CONT and LONG_RELEASE events without previous LONG event are supposed to yield no trigger
121         assertThat(contButtonVirtualDatapoint.getValue(), nullValue());
122         assertThat(releaseButtonVirtualDatapoint.getValue(), nullValue());
123         assertThat(crapButtonVirtualDatapoint, nullValue());
124     }
125
126     private HmDatapoint createPressDatapoint(String channelName, Object value) {
127         HmDatapoint pressDp = new HmDatapoint(channelName, "", HmValueType.ACTION, value, true, HmParamsetType.VALUES);
128         HmChannel hmChannel = new HmChannel(channelName, 1);
129         HmDevice device = new HmDevice("ABC12345", HmInterface.RF, "HM-MOCK", "mockid", "mockid", "mockfw");
130         hmChannel.setDevice(device);
131         device.addChannel(hmChannel);
132         hmChannel.addDatapoint(pressDp);
133         pressDp.setChannel(hmChannel);
134         bvdpHandler.initialize(device);
135
136         return pressDp;
137     }
138
139     private HmDatapoint createPressDatapointFrom(HmDatapoint originalDatapoint, String channelName, Object value) {
140         HmDatapoint pressDp = new HmDatapoint(channelName, "", HmValueType.ACTION, value, true, HmParamsetType.VALUES);
141         HmChannel hmChannel = originalDatapoint.getChannel();
142         hmChannel.addDatapoint(pressDp);
143         pressDp.setChannel(hmChannel);
144
145         return pressDp;
146     }
147
148     private HmDatapoint getButtonVirtualDatapoint(HmDatapoint originalDatapoint) {
149         return originalDatapoint.getChannel().getDatapoints().stream()
150                 .filter(dp -> HomematicConstants.VIRTUAL_DATAPOINT_NAME_BUTTON.equals(dp.getName())).findFirst()
151                 .orElse(null);
152     }
153
154     /**
155      * Mock parts of {@linkplain org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway}
156      */
157     private class MockEventReceiver {
158
159         public void eventReceived(HmDatapoint dp) throws IOException, HomematicClientException {
160             if (bvdpHandler.canHandleEvent(dp)) {
161                 bvdpHandler.handleEvent(null, dp);
162             }
163             if (dp.isPressDatapoint() && MiscUtils.isTrueValue(dp.getValue())) {
164                 disableDatapoint(dp);
165             }
166         }
167
168         private void disableDatapoint(HmDatapoint dp) {
169             new Thread(() -> {
170                 try {
171                     Thread.sleep(DISABLE_DATAPOINT_DELAY);
172                     dp.setValue(Boolean.FALSE);
173                 } catch (InterruptedException e) {
174                 }
175             }).start();
176         }
177     }
178 }