]> git.basschouten.com Git - openhab-addons.git/blob
5ce78d1748c86db3208bab89991b58ede8e0a3b0
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.loxone.internal.controls;
14
15 import static org.hamcrest.CoreMatchers.*;
16 import static org.junit.Assert.*;
17
18 import java.io.BufferedReader;
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
21 import java.math.BigDecimal;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.stream.Collectors;
26
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.openhab.binding.loxone.internal.types.LxUuid;
30 import org.openhab.core.library.types.DecimalType;
31 import org.openhab.core.library.types.OnOffType;
32 import org.openhab.core.library.types.UpDownType;
33 import org.openhab.core.types.StateOption;
34 import org.openhab.core.types.UnDefType;
35
36 /**
37  * Test class for (@link LxControlSwitch}
38  *
39  * @author Pawel Pieczul - initial contribution
40  *
41  */
42 public class LxControlLightControllerV2Test extends LxControlTest {
43     @Before
44     public void setup() {
45         setupControl("1076668f-0101-7076-ffff403fb0c34b9e", "0b734138-03ac-03f0-ffff403fb0c34b9e",
46                 "0b734138-033e-02d4-ffff403fb0c34b9e", "Lighting controller");
47     }
48
49     @Test
50     public void testControlCreation() {
51         testControlCreation(LxControlLightControllerV2.class, 1, 5, 1, 6, 4);
52         testSubControl(LxControlSwitch.class, "Overall Switch");
53         testSubControl(LxControlSwitch.class, "Hall Study Lights");
54         testSubControl(LxControlSwitch.class, "Roof Lights");
55         testSubControl(LxControlSwitch.class, "Hall Left Lights");
56         testSubControl(LxControlSwitch.class, "Hall Right Lights");
57     }
58
59     @Test
60     public void testChannels() {
61         testChannel("Number", Collections.singleton("Scene"));
62     }
63
64     @Test
65     public void testCommands() {
66         for (int i = 0; i < 20; i++) {
67             executeCommand(UpDownType.UP);
68             testAction("plus");
69             executeCommand(UpDownType.DOWN);
70             testAction("minus");
71         }
72         executeCommand(new DecimalType(1));
73         testAction(null);
74
75         loadMoodList1();
76
77         executeCommand(new DecimalType(0));
78         testAction(null);
79         executeCommand(new DecimalType(1));
80         testAction(null);
81         executeCommand(new DecimalType(2));
82         testAction("changeTo/2");
83         executeCommand(new DecimalType(3));
84         testAction("changeTo/3");
85         executeCommand(new DecimalType(4));
86         testAction("changeTo/4");
87         executeCommand(new DecimalType(5));
88         testAction("changeTo/5");
89         executeCommand(new DecimalType(6));
90         testAction(null);
91         executeCommand(new DecimalType(777));
92         testAction("changeTo/777");
93         executeCommand(new DecimalType(778));
94         testAction("changeTo/778");
95         executeCommand(new DecimalType(779));
96         testAction(null);
97         clearMoodList();
98     }
99
100     @Test
101     public void testMoodListChanges() {
102         for (int i = 0; i < 20; i++) {
103             loadMoodList1();
104             loadMoodList2();
105         }
106         clearMoodList();
107     }
108
109     @Test
110     public void testActiveMoodChanges() {
111         loadMoodList2();
112         for (int i = 0; i < 10; i++) {
113             changeLoxoneState("activemoods", "[4]");
114             testActiveMoods(779, 4);
115             changeLoxoneState("activemoods", "[4,6]");
116             testActiveMoods(779, 4, 6);
117             changeLoxoneState("activemoods", "[4,6,7,8,5]");
118             testActiveMoods(779, 4, 6, 7, 8, 5);
119             changeLoxoneState("activemoods", "[4,6,7,8,5,777,778]");
120             testActiveMoods(779, 4, 6, 7, 8, 5, 777, 778);
121             changeLoxoneState("activemoods", "[6,8,777]");
122             testActiveMoods(779, 6, 8, 777);
123             changeLoxoneState("activemoods", "[779]");
124             testActiveMoods(779, 779);
125             changeLoxoneState("activemoods", "[1,2,3,500,900]");
126             testActiveMoods(779);
127             changeLoxoneState("activemoods", "[1,2,3,6,500,900]");
128             testActiveMoods(779, 6);
129             changeLoxoneState("activemoods", "[5]");
130             testActiveMoods(779, 5);
131             changeLoxoneState("activemoods", "[778]");
132             testActiveMoods(779, 778);
133         }
134         clearMoodList();
135     }
136
137     @Test
138     public void testMoodAddRemove() {
139         loadMoodList1();
140         for (int i = 0; i < 10; i++) {
141             handler.extraControls.values().forEach(c -> {
142                 LxControlMood m = (LxControlMood) c;
143                 if (!m.getId().equals(778)) {
144                     executeCommand(m, OnOffType.ON);
145                     testAction("addMood/" + m.getId());
146                     executeCommand(m, OnOffType.OFF);
147                     testAction("removeMood/" + m.getId());
148                 }
149             });
150         }
151         clearMoodList();
152     }
153
154     private void testActiveMoods(Integer offId, Integer... moods) {
155         List<Integer> ids = new ArrayList<>();
156         for (Integer id : moods) {
157             if (!offId.equals(id)) {
158                 LxControlMood m = getMood(id);
159                 testChannelState(m, OnOffType.ON);
160             }
161             ids.add(id);
162         }
163         handler.extraControls.values().stream()
164                 .filter(c -> !ids.contains(((LxControlMood) c).getId()) && !((LxControlMood) c).getId().equals(offId))
165                 .forEach(c -> testChannelState(c, OnOffType.OFF));
166
167         if (ids.size() == 1) {
168             testChannelState(new DecimalType(ids.get(0)));
169         } else {
170             testChannelState(UnDefType.UNDEF);
171         }
172     }
173
174     private void loadMoodList1() {
175         String list = loadMoodList("MoodList1.json");
176         changeLoxoneState("moodlist", list);
177         List<StateOption> options = new ArrayList<>();
178         options.add(new StateOption("2", "Side Lights"));
179         options.add(new StateOption("3", "Play Lights"));
180         options.add(new StateOption("4", "Study Only"));
181         options.add(new StateOption("5", "Low Lights"));
182         options.add(new StateOption("777", "Bright"));
183         options.add(new StateOption("778", "Off"));
184         testMoodList(options, 778);
185     }
186
187     private void loadMoodList2() {
188         String list = loadMoodList("MoodList2.json");
189         changeLoxoneState("moodlist", list);
190         List<StateOption> options = new ArrayList<>();
191         options.add(new StateOption("4", "Study Only Changed Name")); // changed name
192         options.add(new StateOption("5", "Low Lights")); // same as in list 1
193         options.add(new StateOption("6", "Play Lights")); // changed id
194         options.add(new StateOption("7", "New Mood 1"));
195         options.add(new StateOption("8", "New Mood 2"));
196         options.add(new StateOption("777", "Bright"));
197         options.add(new StateOption("778", "Off"));
198         options.add(new StateOption("779", "New Off"));
199         testMoodList(options, 779);
200     }
201
202     private LxControlMood getMood(Integer id) {
203         LxControl ctrl = handler.extraControls.get(new LxUuid("1076668f-0101-7076-ffff403fb0c34b9e-M" + id));
204         assertNotNull(ctrl);
205         assertThat(ctrl, is(instanceOf(LxControlMood.class)));
206         return (LxControlMood) ctrl;
207     }
208
209     private void clearMoodList() {
210         changeLoxoneState("moodlist", "[]");
211         List<StateOption> options = new ArrayList<>();
212         testMoodList(options, 0);
213     }
214
215     private void testMoodList(List<StateOption> options, Integer offId) {
216         assertEquals(options.size(), handler.extraControls.size());
217         if (options.isEmpty()) {
218             return;
219         }
220         Integer min = null;
221         Integer max = null;
222         for (StateOption o : options) {
223             testMood(o.getLabel(), o.getValue(), o.getValue().equals(offId.toString()));
224             Integer id = Integer.parseInt(o.getValue());
225             assertNotNull(id);
226             if (min == null || id < min) {
227                 min = id;
228             }
229             if (max == null || id > max) {
230                 max = id;
231             }
232         }
233         assertNotNull(min);
234         assertNotNull(max);
235         testChannel("Number", null, new BigDecimal(min), new BigDecimal(max), BigDecimal.ONE, null, false, options,
236                 Collections.singleton("Scene"));
237     }
238
239     private void testMood(String name, String id, boolean isStatic) {
240         LxControlMood mood = getMood(Integer.parseInt(id));
241         assertEquals(new LxUuid("0b734138-03ac-03f0-ffff403fb0c34b9e"), mood.getRoom().getUuid());
242         assertEquals(new LxUuid("0b734138-033e-02d4-ffff403fb0c34b9e"), mood.getCategory().getUuid());
243         assertEquals(name, mood.getName());
244         assertEquals(id, mood.getId().toString());
245         if (isStatic) {
246             assertEquals(0, mood.getChannels().size());
247         } else {
248             assertEquals(1, mood.getChannels().size());
249             testChannel(mood, "Switch", Collections.singleton("Lighting"));
250         }
251     }
252
253     private String loadMoodList(String name) {
254         InputStream stream = LxControlLightControllerV2Test.class.getResourceAsStream(name);
255         assertNotNull(stream);
256         BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
257         assertNotNull(reader);
258         String msg = reader.lines().collect(Collectors.joining(System.lineSeparator()));
259         assertNotNull(msg);
260         // mood list comes as a single line JSON from Loxone Miniserver
261         msg = msg.replaceAll("[\\t+\\n+]", "");
262         return msg;
263     }
264 }