]> git.basschouten.com Git - openhab-addons.git/blob
c45cc3e0e53c7ede7669e9d34b9df71f70aae1c5
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.boschshc.internal.devices.relay;
14
15 import static org.hamcrest.CoreMatchers.notNullValue;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.hamcrest.Matchers.is;
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.ArgumentMatchers.eq;
20 import static org.mockito.Mockito.times;
21 import static org.mockito.Mockito.verify;
22
23 import java.time.Instant;
24 import java.util.List;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.TimeoutException;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.junit.jupiter.api.Test;
31 import org.mockito.ArgumentCaptor;
32 import org.mockito.Captor;
33 import org.openhab.binding.boschshc.internal.devices.AbstractPowerSwitchHandlerTest;
34 import org.openhab.binding.boschshc.internal.devices.BoschSHCBindingConstants;
35 import org.openhab.binding.boschshc.internal.exceptions.BoschSHCException;
36 import org.openhab.binding.boschshc.internal.services.childprotection.dto.ChildProtectionServiceState;
37 import org.openhab.binding.boschshc.internal.services.impulseswitch.ImpulseSwitchService;
38 import org.openhab.binding.boschshc.internal.services.impulseswitch.dto.ImpulseSwitchServiceState;
39 import org.openhab.core.library.types.DateTimeType;
40 import org.openhab.core.library.types.DecimalType;
41 import org.openhab.core.library.types.OnOffType;
42 import org.openhab.core.thing.ChannelUID;
43 import org.openhab.core.thing.ThingTypeUID;
44 import org.openhab.core.types.UnDefType;
45
46 import com.google.gson.JsonElement;
47 import com.google.gson.JsonParser;
48
49 /**
50  * Unit tests for {@link RelayHandler}.
51  * 
52  * @author David Pace - Initial contributions
53  *
54  */
55 @NonNullByDefault
56 class RelayHandlerTest extends AbstractPowerSwitchHandlerTest<RelayHandler> {
57
58     private @Captor @NonNullByDefault({}) ArgumentCaptor<ChildProtectionServiceState> childProtectionServiceStateCaptor;
59
60     private @Captor @NonNullByDefault({}) ArgumentCaptor<ImpulseSwitchServiceState> impulseSwitchServiceStateCaptor;
61
62     @Override
63     protected RelayHandler createFixture() {
64         return new RelayHandler(getThing());
65     }
66
67     @Override
68     protected ThingTypeUID getThingTypeUID() {
69         return BoschSHCBindingConstants.THING_TYPE_RELAY;
70     }
71
72     @Override
73     protected String getDeviceID() {
74         return "hdm:ZigBee:30XXXXXXXXXXXXXX";
75     }
76
77     @Test
78     void testUpdateChannelsCommunicationQualityService() {
79         String json = """
80                 {
81                     "@type": "communicationQualityState",
82                     "quality": "UNKNOWN"
83                 }
84                 """;
85         JsonElement jsonObject = JsonParser.parseString(json);
86
87         getFixture().processUpdate("CommunicationQuality", jsonObject);
88         verify(getCallback()).stateUpdated(
89                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SIGNAL_STRENGTH),
90                 new DecimalType(0));
91
92         json = """
93                 {
94                     "@type": "communicationQualityState",
95                     "quality": "GOOD"
96                 }
97                 """;
98         jsonObject = JsonParser.parseString(json);
99
100         getFixture().processUpdate("CommunicationQuality", jsonObject);
101         verify(getCallback()).stateUpdated(
102                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_SIGNAL_STRENGTH),
103                 new DecimalType(4));
104     }
105
106     @Test
107     void testUpdateChannelsChildProtectionService() {
108         String json = """
109                 {
110                     "@type": "ChildProtectionState",
111                     "childLockActive": true
112                 }
113                 """;
114         JsonElement jsonObject = JsonParser.parseString(json);
115
116         getFixture().processUpdate("ChildProtection", jsonObject);
117         verify(getCallback()).stateUpdated(
118                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_PROTECTION), OnOffType.ON);
119     }
120
121     @Test
122     void testUpdateChannelsImpulseSwitchService()
123             throws BoschSHCException, InterruptedException, TimeoutException, ExecutionException {
124         configureImpulseSwitchMode();
125         String json = """
126                 {
127                   "@type": "ImpulseSwitchState",
128                   "impulseState": true,
129                   "impulseLength": 100,
130                   "instantOfLastImpulse": "2024-04-14T15:52:31.677366Z"
131                 }
132                 """;
133         JsonElement jsonObject = JsonParser.parseString(json);
134
135         getFixture().processUpdate("ImpulseSwitch", jsonObject);
136         verify(getCallback()).stateUpdated(
137                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_SWITCH), OnOffType.ON);
138         verify(getCallback(), times(2)).stateUpdated(
139                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_LENGTH),
140                 new DecimalType(100));
141         verify(getCallback(), times(2)).stateUpdated(
142                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_INSTANT_OF_LAST_IMPULSE),
143                 new DateTimeType("2024-04-14T15:52:31.677366Z"));
144     }
145
146     @Test
147     void testUpdateChannelsImpulseSwitchServiceNoInstantOfLastImpulse()
148             throws BoschSHCException, InterruptedException, TimeoutException, ExecutionException {
149         configureImpulseSwitchMode();
150         String json = """
151                 {
152                   "@type": "ImpulseSwitchState",
153                   "impulseState": true,
154                   "impulseLength": 100
155                 }
156                 """;
157         JsonElement jsonObject = JsonParser.parseString(json);
158
159         getFixture().processUpdate("ImpulseSwitch", jsonObject);
160         verify(getCallback()).stateUpdated(
161                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_SWITCH), OnOffType.ON);
162         verify(getCallback(), times(2)).stateUpdated(
163                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_LENGTH),
164                 new DecimalType(100));
165         verify(getCallback()).stateUpdated(
166                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_INSTANT_OF_LAST_IMPULSE),
167                 UnDefType.NULL);
168     }
169
170     private void configureImpulseSwitchMode()
171             throws BoschSHCException, InterruptedException, TimeoutException, ExecutionException {
172         getDevice().deviceServiceIds = List.of(ImpulseSwitchService.IMPULSE_SWITCH_SERVICE_NAME);
173         getFixture().initialize();
174
175         assertThat(getFixture().getThing().getChannel(BoschSHCBindingConstants.CHANNEL_IMPULSE_SWITCH),
176                 is(notNullValue()));
177         assertThat(getFixture().getThing().getChannel(BoschSHCBindingConstants.CHANNEL_IMPULSE_LENGTH),
178                 is(notNullValue()));
179         assertThat(getFixture().getThing().getChannel(BoschSHCBindingConstants.CHANNEL_INSTANT_OF_LAST_IMPULSE),
180                 is(notNullValue()));
181
182         @Nullable
183         JsonElement impulseSwitchServiceState = JsonParser.parseString("""
184                 {
185                   "@type": "ImpulseSwitchState",
186                   "impulseState": false,
187                   "impulseLength": 100,
188                   "instantOfLastImpulse": "2024-04-14T15:52:31.677366Z"
189                 }
190                 """);
191         getFixture().processUpdate(ImpulseSwitchService.IMPULSE_SWITCH_SERVICE_NAME, impulseSwitchServiceState);
192     }
193
194     @Test
195     void testHandleCommandChildProtection()
196             throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
197         getFixture().handleCommand(
198                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_PROTECTION), OnOffType.ON);
199         verify(getBridgeHandler()).putState(eq(getDeviceID()), eq("ChildProtection"),
200                 childProtectionServiceStateCaptor.capture());
201         ChildProtectionServiceState state = childProtectionServiceStateCaptor.getValue();
202         assertThat(state.childLockActive, is(true));
203     }
204
205     @Test
206     void testHandleCommandChildProtectionInvalidCommand()
207             throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
208         getFixture().handleCommand(
209                 new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_CHILD_PROTECTION),
210                 DecimalType.ZERO);
211         verify(getBridgeHandler(), times(0)).putState(eq(getDeviceID()), eq("ChildProtection"), any());
212     }
213
214     @Test
215     void testHandleCommandImpulseStateOn()
216             throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
217         configureImpulseSwitchMode();
218
219         Instant testDate = Instant.now();
220         getFixture().setCurrentDateTimeProvider(() -> testDate);
221
222         getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_SWITCH),
223                 OnOffType.ON);
224         verify(getBridgeHandler()).putState(eq(getDeviceID()), eq(ImpulseSwitchService.IMPULSE_SWITCH_SERVICE_NAME),
225                 impulseSwitchServiceStateCaptor.capture());
226         ImpulseSwitchServiceState state = impulseSwitchServiceStateCaptor.getValue();
227         assertThat(state.impulseState, is(true));
228         assertThat(state.impulseLength, is(100));
229         assertThat(state.instantOfLastImpulse, is(testDate.toString()));
230     }
231
232     @Test
233     void testHandleCommandImpulseLength()
234             throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
235         configureImpulseSwitchMode();
236
237         Instant testDate = Instant.now();
238         getFixture().setCurrentDateTimeProvider(() -> testDate);
239
240         getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_LENGTH),
241                 new DecimalType(15));
242         verify(getBridgeHandler()).putState(eq(getDeviceID()), eq(ImpulseSwitchService.IMPULSE_SWITCH_SERVICE_NAME),
243                 impulseSwitchServiceStateCaptor.capture());
244         ImpulseSwitchServiceState state = impulseSwitchServiceStateCaptor.getValue();
245         assertThat(state.impulseState, is(false));
246         assertThat(state.impulseLength, is(15));
247         assertThat(state.instantOfLastImpulse, is("2024-04-14T15:52:31.677366Z"));
248     }
249
250     @Test
251     void testHandleCommandImpulseStateOff()
252             throws InterruptedException, TimeoutException, ExecutionException, BoschSHCException {
253         getFixture().handleCommand(new ChannelUID(getThing().getUID(), BoschSHCBindingConstants.CHANNEL_IMPULSE_SWITCH),
254                 OnOffType.OFF);
255         verify(getBridgeHandler(), times(0)).postState(eq(getDeviceID()),
256                 eq(ImpulseSwitchService.IMPULSE_SWITCH_SERVICE_NAME), any());
257     }
258 }