]> git.basschouten.com Git - openhab-addons.git/blob
751c7ec394fa1edc7637ea4237399755828779e8
[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.tradfri.internal.discovery;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.junit.jupiter.api.Assertions.*;
18 import static org.mockito.Mockito.when;
19 import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*;
20 import static org.openhab.binding.tradfri.internal.config.TradfriDeviceConfig.CONFIG_ID;
21
22 import java.util.Collection;
23
24 import org.junit.jupiter.api.AfterEach;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.junit.jupiter.api.extension.ExtendWith;
28 import org.mockito.Mock;
29 import org.mockito.junit.jupiter.MockitoExtension;
30 import org.mockito.junit.jupiter.MockitoSettings;
31 import org.mockito.quality.Strictness;
32 import org.openhab.binding.tradfri.internal.handler.TradfriGatewayHandler;
33 import org.openhab.core.config.discovery.DiscoveryListener;
34 import org.openhab.core.config.discovery.DiscoveryResult;
35 import org.openhab.core.config.discovery.DiscoveryResultFlag;
36 import org.openhab.core.config.discovery.DiscoveryService;
37 import org.openhab.core.thing.ThingTypeUID;
38 import org.openhab.core.thing.ThingUID;
39 import org.openhab.core.thing.binding.builder.BridgeBuilder;
40
41 import com.google.gson.JsonObject;
42 import com.google.gson.JsonParser;
43
44 /**
45  * Tests for {@link TradfriDiscoveryService}.
46  *
47  * @author Kai Kreuzer - Initial contribution
48  * @author Christoph Weitkamp - Added support for remote controller and motion sensor devices (read-only battery level)
49  * @author Vivien Boistuaud - Added unit test for Air Purifier
50  */
51 @ExtendWith(MockitoExtension.class)
52 @MockitoSettings(strictness = Strictness.LENIENT)
53 public class TradfriDiscoveryServiceTest {
54
55     private static final ThingUID GATEWAY_THING_UID = new ThingUID("tradfri:gateway:1");
56
57     private @Mock TradfriGatewayHandler handler;
58
59     private final DiscoveryListener listener = new DiscoveryListener() {
60         @Override
61         public void thingRemoved(DiscoveryService source, ThingUID thingUID) {
62         }
63
64         @Override
65         public void thingDiscovered(DiscoveryService source, DiscoveryResult result) {
66             discoveryResult = result;
67         }
68
69         @Override
70         public Collection<ThingUID> removeOlderResults(DiscoveryService source, long timestamp,
71                 Collection<ThingTypeUID> thingTypeUIDs, ThingUID bridgeUID) {
72             return null;
73         }
74     };
75
76     private DiscoveryResult discoveryResult;
77
78     private TradfriDiscoveryService discovery;
79
80     @BeforeEach
81     public void setUp() {
82         when(handler.getThing()).thenReturn(BridgeBuilder.create(GATEWAY_TYPE_UID, "1").build());
83
84         discovery = new TradfriDiscoveryService();
85         discovery.setThingHandler(handler);
86         discovery.addDiscoveryListener(listener);
87     }
88
89     @AfterEach
90     public void cleanUp() {
91         discoveryResult = null;
92     }
93
94     @Test
95     public void correctSupportedTypes() {
96         assertThat(discovery.getSupportedThingTypes().size(), is(10));
97         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_DIMMABLE_LIGHT));
98         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_COLOR_TEMP_LIGHT));
99         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_COLOR_LIGHT));
100         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_DIMMER));
101         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_MOTION_SENSOR));
102         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_REMOTE_CONTROL));
103         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL));
104         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_ONOFF_PLUG));
105         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_BLINDS));
106         assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_AIR_PURIFIER));
107     }
108
109     @Test
110     public void validDiscoveryResultWhiteLightW() {
111         String json = "{\"9001\":\"TRADFRI bulb E27 W opal 1000lm\",\"9002\":1492856270,\"9020\":1507194357,\"9003\":65537,\"3311\":[{\"5850\":1,\"5851\":254,\"9003\":0}],\"9054\":0,\"5750\":2,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI bulb E27 W opal 1000lm\",\"2\":\"\",\"3\":\"1.2.214\",\"6\":1}}";
112         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
113
114         discovery.onUpdate("65537", data);
115
116         assertNotNull(discoveryResult);
117         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
118         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0100:1:65537")));
119         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_DIMMABLE_LIGHT));
120         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
121         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65537));
122         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
123     }
124
125     @Test
126     public void validDiscoveryResultWhiteLightWS() {
127         String json = "{\"9001\":\"TRADFRI bulb E27 WS opal 980lm\",\"9002\":1492955148,\"9020\":1507200447,\"9003\":65537,\"3311\":[{\"5710\":26909,\"5850\":1,\"5851\":203,\"5707\":0,\"5708\":0,\"5709\":30140,\"5711\":370,\"5706\":\"f1e0b5\",\"9003\":0}],\"9054\":0,\"5750\":2,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI bulb E27 WS opal 980lm\",\"2\":\"\",\"3\":\"1.2.217\",\"6\":1}}";
128         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
129
130         discovery.onUpdate("65537", data);
131
132         assertNotNull(discoveryResult);
133         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
134         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0220:1:65537")));
135         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_COLOR_TEMP_LIGHT));
136         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
137         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65537));
138         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
139     }
140
141     @Test
142     public void validDiscoveryResultWhiteLightWSWithIncompleteJson() {
143         // We do not always receive a COLOR = "5706" attribute, even the light supports it - but the gateway does not
144         // seem to have this information, if the bulb is unreachable.
145         String json = "{\"9001\":\"TRADFRI bulb E27 WS opal 980lm\",\"9002\":1492955148,\"9020\":1506968670,\"9003\":65537,\"3311\":[{\"9003\":0}],\"9054\":0,\"5750\":2,\"9019\":0,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI bulb E27 WS opal 980lm\",\"2\":\"\",\"3\":\"1.2.217\",\"6\":1}}";
146         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
147
148         discovery.onUpdate("65537", data);
149
150         assertNotNull(discoveryResult);
151         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
152         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0220:1:65537")));
153         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_COLOR_TEMP_LIGHT));
154         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
155         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65537));
156         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
157     }
158
159     @Test
160     public void validDiscoveryResultColorLightCWS() {
161         String json = "{\"9001\":\"TRADFRI bulb E27 CWS opal 600lm\",\"9002\":1505151864,\"9020\":1505433527,\"9003\":65550,\"9019\":1,\"9054\":0,\"5750\":2,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI bulb E27 CWS opal 600lm\",\"2\":\"\",\"3\":\"1.3.002\",\"6\":1},\"3311\":[{\"5850\":1,\"5708\":0,\"5851\":254,\"5707\":0,\"5709\":33137,\"5710\":27211,\"5711\":0,\"5706\":\"efd275\",\"9003\":0}]}";
162         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
163
164         discovery.onUpdate("65550", data);
165
166         assertNotNull(discoveryResult);
167         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
168         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0210:1:65550")));
169         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_COLOR_LIGHT));
170         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
171         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65550));
172         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
173     }
174
175     @Test
176     public void validDiscoveryResultAlternativeColorLightCWS() {
177         String json = "{\"3311\":[{\"5850\":1,\"5709\":32886,\"5851\":216,\"5707\":5309,\"5708\":52400,\"5710\":27217,\"5706\":\"efd275\",\"9003\":0}],\"9001\":\"Mushroom lamp\",\"9002\":1571036916,\"9020\":1571588312,\"9003\":65539,\"9054\":0,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI bulb E27 C\\/WS opal 600\",\"2\":\"\",\"3\":\"1.3.009\",\"6\":1},\"5750\":2}";
178         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
179
180         discovery.onUpdate("65539", data);
181
182         assertNotNull(discoveryResult);
183         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
184         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0210:1:65539")));
185         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_COLOR_LIGHT));
186         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
187         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65539));
188         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
189     }
190
191     @Test
192     public void validDiscoveryResultRemoteControl() {
193         String json = "{\"9001\":\"TRADFRI remote control\",\"9002\":1492843083,\"9020\":1506977986,\"9003\":65536,\"9054\":0,\"5750\":0,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI remote control\",\"2\":\"\",\"3\":\"1.2.214\",\"6\":3,\"9\":47},\"15009\":[{\"9003\":0}]}";
194         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
195
196         discovery.onUpdate("65536", data);
197
198         assertNotNull(discoveryResult);
199         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
200         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0830:1:65536")));
201         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_REMOTE_CONTROL));
202         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
203         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65536));
204         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
205     }
206
207     @Test
208     public void validDiscoveryResultWirelessDimmer() {
209         String json = "{\"9001\":\"TRADFRI wireless dimmer\",\"9002\":1492843083,\"9020\":1506977986,\"9003\":65536,\"9054\":0,\"5750\":0,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI wireless dimmer\",\"2\":\"\",\"3\":\"1.2.214\",\"6\":3,\"9\":47},\"15009\":[{\"9003\":0}]}";
210         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
211
212         discovery.onUpdate("65536", data);
213
214         assertNotNull(discoveryResult);
215         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
216         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0820:1:65536")));
217         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_DIMMER));
218         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
219         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65536));
220         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
221     }
222
223     @Test
224     public void validDiscoveryResultMotionSensor() {
225         String json = "{\"9001\":\"TRADFRI motion sensor\",\"9002\":1492955083,\"9020\":1507120083,\"9003\":65538,\"9054\":0,\"5750\":4,\"9019\":1,\"3\":{\"0\":\"IKEA of Sweden\",\"1\":\"TRADFRI motion sensor\",\"2\":\"\",\"3\":\"1.2.214\",\"6\":3,\"9\":60},\"3300\":[{\"9003\":0}]}";
226         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
227
228         discovery.onUpdate("65538", data);
229
230         assertNotNull(discoveryResult);
231         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
232         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0107:1:65538")));
233         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_MOTION_SENSOR));
234         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
235         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65538));
236         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
237     }
238
239     @Test
240     public void validDiscoveryResultAirPurifier() {
241         String json = "{\"3\":{\"0\":\"IKEAofSweden\",\"1\":\"STARKVINDAirpurifier\",\"2\":\"\",\"3\":\"1.0.033\",\"6\":1,\"7\":4364},\"5750\":10,\"9001\":\"Luftreiniger\",\"9002\":1633096623,\"9003\":65548,\"9019\":1,\"9020\":1633096633,\"9054\":0,\"15025\":[{\"5900\":1,\"5902\":2,\"5903\":0,\"5904\":259200,\"5905\":0,\"5906\":0,\"5907\":5,\"5908\":10,\"5909\":2,\"5910\":259198,\"9003\":0}]}";
242         JsonObject data = JsonParser.parseString(json).getAsJsonObject();
243
244         discovery.onUpdate("65548", data);
245
246         assertNotNull(discoveryResult);
247         assertThat(discoveryResult.getFlag(), is(DiscoveryResultFlag.NEW));
248         assertThat(discoveryResult.getThingUID(), is(new ThingUID("tradfri:0007:1:65548")));
249         assertThat(discoveryResult.getThingTypeUID(), is(THING_TYPE_AIR_PURIFIER));
250         assertThat(discoveryResult.getBridgeUID(), is(GATEWAY_THING_UID));
251         assertThat(discoveryResult.getProperties().get(CONFIG_ID), is(65548));
252         assertThat(discoveryResult.getRepresentationProperty(), is(CONFIG_ID));
253     }
254 }