2 * Copyright (c) 2010-2022 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.hdpowerview;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.junit.jupiter.api.Test;
20 import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
21 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase;
22 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities;
23 import org.openhab.core.library.types.PercentType;
24 import org.openhab.core.types.State;
25 import org.openhab.core.types.UnDefType;
28 * Unit tests for Shade Position setting and getting.
30 * @author Andrew Fiddian-Green - Initial contribution
33 public class ShadePositionTest {
35 private final ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase();
38 * General tests of the database of known types.
41 public void testKnownTypesDatabase() {
42 assertTrue(db.isTypeInDatabase(4));
43 assertTrue(db.isCapabilitiesInDatabase(0));
45 assertTrue(db.getCapabilities(0).supportsPrimary());
46 assertTrue(db.getCapabilities(1).supportsTiltOnClosed());
47 assertTrue(db.getCapabilities(2).supportsTilt180());
48 assertTrue(db.getCapabilities(2).supportsTiltAnywhere());
49 assertTrue(db.getCapabilities(3).supportsTilt180());
50 assertTrue(db.getCapabilities(3).supportsTiltAnywhere());
51 assertTrue(db.getCapabilities(5).supportsTilt180());
52 assertFalse(db.getCapabilities(5).supportsPrimary());
53 assertTrue(db.getCapabilities(6).isPrimaryInverted());
54 assertTrue(db.getCapabilities(7).supportsSecondary());
55 assertTrue(db.getCapabilities(8).supportsSecondaryOverlapped());
56 assertTrue(db.getCapabilities(9).supportsSecondaryOverlapped());
57 assertTrue(db.getCapabilities(9).supportsTiltOnClosed());
59 assertEquals(db.getType(4).getCapabilities(), 0);
60 assertEquals(db.getType(-1).getCapabilities(), -1);
62 assertFalse(db.isTypeInDatabase(99));
63 assertFalse(db.isCapabilitiesInDatabase(99));
65 assertFalse(db.getCapabilities(0).isPrimaryInverted());
66 assertFalse(db.getCapabilities(-1).isPrimaryInverted());
67 assertFalse(db.getCapabilities(99).isPrimaryInverted());
69 assertFalse(db.getCapabilities(0).supportsSecondary());
70 assertFalse(db.getCapabilities(-1).supportsSecondary());
71 assertFalse(db.getCapabilities(99).supportsSecondary());
75 * Helper method; test if shade position is a PercentType and that its value is correct.
77 * @param position the shade position
78 * @param value the test value to compare with
80 private void assertShadePosition(State position, int value) {
81 assertEquals(PercentType.class, position.getClass());
82 assertEquals(value, ((PercentType) position).intValue());
86 * Test parsing of Capabilities 1 ShadePosition (shade fully up).
90 public void testCaps1ShadePositionParsingFullyUp() {
91 Capabilities capabilities = db.getCapabilities(1);
92 ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
94 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
95 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
96 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
100 * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 1)).
104 public void testCaps1ShadePositionParsingShadeFullyDown1() {
105 Capabilities capabilities = db.getCapabilities(1);
106 ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
108 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
109 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
110 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
114 * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2)).
118 public void testCaps1ShadePositionParsingShadeFullyDown2() {
119 Capabilities capabilities = db.getCapabilities(1);
120 ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0);
122 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
123 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
124 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
128 * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2) and vane fully open).
132 public void testCaps1ShadePositionParsingShadeFullyDownVaneOpen() {
133 Capabilities capabilities = db.getCapabilities(1);
134 ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88);
136 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
137 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
138 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88);
142 * On dual rail shades, it should not be possible to drive the upper rail below the lower rail, or vice-versa. So
143 * the binding code applies constraints on setting such positions. This test checks that the constraint code is
147 public void testDualRailConstraints() {
148 Capabilities capabilities = db.getCapabilities(7);
149 ShadePosition test = new ShadePosition();
151 // ==== OK !! primary at bottom, secondary at top ====
152 test.setPosition(capabilities, PRIMARY_POSITION, 100).setPosition(capabilities, SECONDARY_POSITION, 0);
153 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
154 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
155 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
157 // ==== OK !! primary at middle, secondary at top ====
158 test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 0);
159 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
160 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
161 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
163 // ==== OK !! primary at middle, secondary at middle ====
164 test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 50);
165 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
166 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
167 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
169 // ==== IMPOSSIBLE !! secondary at middle, primary above => test the constraining code ====
170 test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
171 test.setPosition(capabilities, SECONDARY_POSITION, 40).setPosition(capabilities, PRIMARY_POSITION, 25);
172 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 40);
173 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 40);
174 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
176 // ==== OK !! secondary at middle, primary below ====
177 test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
178 test.setPosition(capabilities, SECONDARY_POSITION, 50).setPosition(capabilities, PRIMARY_POSITION, 75);
179 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 75);
180 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
181 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
183 // ==== IMPOSSIBLE !! primary at middle, secondary below => test the constraining code ====
184 test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
185 test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 75);
186 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60);
187 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 60);
188 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
190 // ==== OK !! primary at middle, secondary above ====
191 test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
192 test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 25);
193 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60);
194 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 25);
195 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
199 * Test parsing of DuoLite shades having a secondary blackout shade.
203 public void testDuoliteShadePositionParsing() {
204 // blackout shades have capabilities 8
205 Capabilities capabilities = db.getCapabilities(8);
209 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
211 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
212 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
213 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
215 // front shade 50% down
216 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 50);
218 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
219 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
220 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
222 // front shade 100% down, back shade 0% down
223 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
225 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
226 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
227 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
229 // front shade 100% down, back shade 0% down (ALTERNATE)
230 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0);
232 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
233 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
234 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
236 // front shade 100% down, back shade 50% down
237 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 50);
239 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
240 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
241 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
243 // front shade 100% down, back shade 100% down
244 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100);
246 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
247 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100);
248 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
252 * Test parsing of DuoLite shades having both a secondary blackout shade, and tilt functionality.
256 public void testDuoliteTiltShadePositionParsing() {
257 // blackout shades with tilt have capabilities 9
258 Capabilities capabilities = db.getCapabilities(9);
262 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
264 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
265 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
266 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
268 // front shade 30% down
269 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30);
271 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 30);
272 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
273 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
275 // front shade 100% down
276 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
278 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
279 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
280 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
283 test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0);
285 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
286 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
287 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
290 test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 30);
292 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
293 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
294 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
297 test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 100);
299 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
300 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
301 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
303 // back shade 0% down
304 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0);
306 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
307 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
308 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
310 // back shade 30% down
311 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 30);
313 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
314 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30);
315 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
317 // back shade 100% down
318 test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100);
320 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
321 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100);
322 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
324 // test constraints on impossible values: primary 30% => tilt 30%
325 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30).setPosition(capabilities,
326 VANE_TILT_POSITION, 30);
328 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
329 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
330 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
332 // test constraints on impossible values: primary 30% => tilt 30% => back shade 30% down
333 test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30)
334 .setPosition(capabilities, VANE_TILT_POSITION, 30).setPosition(capabilities, SECONDARY_POSITION, 30);
336 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
337 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30);
338 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
342 * Test parsing of Capabilities 0 ShadePosition (shade fully up).
346 public void testCaps0ShadePositionParsingFullyUp() {
347 Capabilities capabilities = db.getCapabilities(0);
348 ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
350 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
351 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
352 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
356 * Test parsing of Capabilities 0 ShadePosition (shade fully down).
360 public void testCap0ShadePositionParsingShadeFullyDown() {
361 Capabilities capabilities = db.getCapabilities(0);
362 ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
364 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
365 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
366 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
370 * Helper method; test if shade State is correct.
372 * @param actual the shade State
373 * @param target the test value to compare with
375 private void assertShadePosition(State actual, State target) {
376 assertTrue(target.equals(actual));
380 * Test parsing of Type 44 ShadePosition (shade fully up).
384 public void testType44ShadePositionParsingFullyUp() {
385 Capabilities capabilities = db.getCapabilities(44, null);
386 ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
388 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
389 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
390 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
394 * Test parsing of Type 44 ShadePosition (shade fully down (method 2) and vane fully open).
398 public void testType44ShadePositionParsingShadeFullyDownVaneOpen() {
399 Capabilities capabilities = db.getCapabilities(44, null);
400 ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88);
402 assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
403 assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
404 assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88);