]> git.basschouten.com Git - openhab-addons.git/blob
0ae358f465802ac4fa05886af559eacf792f3d16
[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.onewire.device;
14
15 import static org.junit.Assert.*;
16 import static org.mockito.ArgumentMatchers.eq;
17 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
18
19 import java.util.*;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.ArgumentCaptor;
26 import org.mockito.InOrder;
27 import org.mockito.Mockito;
28 import org.openhab.binding.onewire.internal.OwException;
29 import org.openhab.binding.onewire.internal.device.BAE0910;
30 import org.openhab.binding.onewire.internal.owserver.OwserverDeviceParameter;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.OnOffType;
34 import org.openhab.core.library.types.QuantityType;
35 import org.openhab.core.thing.type.ChannelTypeUID;
36 import org.openhab.core.types.State;
37
38 /**
39  * Tests cases for {@link BAE0910}.
40  *
41  * @author Jan N. Klug - Initial contribution
42  */
43 @NonNullByDefault
44 public class BAE0910Test extends DeviceTestParent<BAE0910> {
45     @Before
46     public void setupMocks() {
47         setupMocks(THING_TYPE_BAE091X, BAE0910.class);
48     }
49
50     // pin 1: counter
51
52     @Test
53     public void counter() {
54         addChannel(CHANNEL_COUNTER, "Number");
55         final BAE0910 testDevice = instantiateDevice();
56         final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
57
58         try {
59             Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
60             Mockito.when(
61                     mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter("/counter"))))
62                     .thenReturn(new DecimalType(34567));
63
64             testDevice.enableChannel(CHANNEL_COUNTER);
65             testDevice.configureChannels(mockBridgeHandler);
66
67             // refresh
68             ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
69             testDevice.refresh(mockBridgeHandler, true);
70             inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
71                     eq(new OwserverDeviceParameter("/counter")));
72             inOrder.verify(mockThingHandler).postUpdate(eq(CHANNEL_COUNTER), stateArgumentCaptor.capture());
73             assertEquals(new DecimalType(34567), stateArgumentCaptor.getValue());
74
75             // write
76             assertFalse(testDevice.writeChannel(mockBridgeHandler, CHANNEL_COUNTER, new DecimalType(12345)));
77
78             inOrder.verifyNoMoreInteractions();
79         } catch (OwException e) {
80             Assert.fail("caught unexpected OwException");
81         }
82     }
83
84     // pin 2: digital2 or pwm1
85
86     @Test
87     public void digitalOut2() {
88         addChannel(CHANNEL_DIGITAL2, "Switch");
89         digitalBaseChannel(CHANNEL_DIGITAL2, bitSet(3, 4), 0, "/out", bitSet(0), true);
90     }
91
92     @Test
93     public void pwm4() {
94         pwmBaseChannel(CHANNEL_PWM_FREQ2, CHANNEL_PWM_DUTY4, "/period2", "/duty4", 2);
95     }
96
97     // pin 6: pio or pwm 3
98
99     @Test
100     public void digital6PioIn() {
101         Map<String, Object> channelConfig = new HashMap<>();
102         channelConfig.put("pulldevice", "pulldown");
103         channelConfig.put("mode", "input");
104         addChannel(CHANNEL_DIGITAL6, "Switch", new Configuration(channelConfig));
105         digitalBaseChannel(CHANNEL_DIGITAL6, bitSet(1, 2, 3, 4), 1, "/pio", bitSet(0), false);
106     }
107
108     @Test
109     public void digital6PioOut() {
110         Map<String, Object> channelConfig = new HashMap<>();
111         channelConfig.put("mode", "output");
112         addChannel(CHANNEL_DIGITAL6, "Switch", new Configuration(channelConfig));
113         digitalBaseChannel(CHANNEL_DIGITAL6, bitSet(0, 3, 4), 1, "/pio", bitSet(0), true);
114     }
115
116     @Test
117     public void pwm3() {
118         pwmBaseChannel(CHANNEL_PWM_FREQ1, CHANNEL_PWM_DUTY3, "/period1", "/duty3", 1);
119     }
120
121     // pin 7: analog, output, pwm2
122
123     @Test
124     public void analog() {
125         Map<String, Object> channelConfig = new HashMap<>();
126         channelConfig.put("hires", "true");
127         addChannel(CHANNEL_VOLTAGE, "Number:ElectricPotential", new Configuration(channelConfig));
128
129         final BAE0910 testDevice = instantiateDevice();
130         final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
131
132         try {
133             Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
134             Mockito.when(mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter("/adc"))))
135                     .thenReturn(new DecimalType(5.2));
136
137             testDevice.enableChannel(CHANNEL_VOLTAGE);
138             testDevice.configureChannels(mockBridgeHandler);
139
140             // test configuration
141             assertEquals(bitSet(3, 4), checkConfiguration(2));
142
143             // refresh
144             ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
145             testDevice.refresh(mockBridgeHandler, true);
146             inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
147                     eq(new OwserverDeviceParameter("/adc")));
148             inOrder.verify(mockThingHandler).postUpdate(eq(CHANNEL_VOLTAGE), stateArgumentCaptor.capture());
149             assertEquals(new QuantityType<>("5.2 V"), stateArgumentCaptor.getValue());
150
151             // write (should fail)
152             assertFalse(testDevice.writeChannel(mockBridgeHandler, CHANNEL_VOLTAGE, new QuantityType<>("3 V")));
153
154             inOrder.verifyNoMoreInteractions();
155         } catch (OwException e) {
156             Assert.fail("caught unexpected OwException");
157         }
158     }
159
160     @Test
161     public void digitalOut7() {
162         addChannel(CHANNEL_DIGITAL7, "Switch");
163         digitalBaseChannel(CHANNEL_DIGITAL7, bitSet(4), 4, "/tpm2c", bitSet(4, 7), true);
164     }
165
166     @Test
167     public void pwm2() {
168         pwmBaseChannel(CHANNEL_PWM_FREQ2, CHANNEL_PWM_DUTY2, "/period2", "/duty2", 2);
169     }
170
171     // pin 8: digital in, digital out or pwm
172
173     @Test
174     public void digitalIn8() {
175         addChannel(CHANNEL_DIGITAL8, "Switch", new ChannelTypeUID(BINDING_ID, "bae-in"));
176         digitalBaseChannel(CHANNEL_DIGITAL8, bitSet(4, 5), 3, "/tpm1c", bitSet(4, 5, 7), false);
177     }
178
179     @Test
180     public void digitalOut8() {
181         addChannel(CHANNEL_DIGITAL8, "Switch");
182         digitalBaseChannel(CHANNEL_DIGITAL8, bitSet(4), 3, "/tpm1c", bitSet(4, 7), true);
183     }
184
185     @Test
186     public void pwm1() {
187         pwmBaseChannel(CHANNEL_PWM_FREQ1, CHANNEL_PWM_DUTY1, "/period1", "/duty1", 1);
188     }
189
190     /**
191      * base test for digital channels
192      *
193      * @param channel channel name
194      * @param configBitSet expected config register
195      * @param configRegister config register number
196      * @param channelParam channel parameter
197      * @param returnBitSet which bitset should be returned on read
198      * @param isOutput if this channel is an output
199      */
200     private void digitalBaseChannel(String channel, BitSet configBitSet, int configRegister, String channelParam,
201             BitSet returnBitSet, boolean isOutput) {
202         final BAE0910 testDevice = instantiateDevice();
203         final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
204
205         try {
206             Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
207             Mockito.when(mockBridgeHandler.readBitSet(eq(testSensorId), eq(new OwserverDeviceParameter(channelParam))))
208                     .thenReturn(returnBitSet);
209
210             testDevice.enableChannel(channel);
211             testDevice.configureChannels(mockBridgeHandler);
212
213             // test configuration
214             assertEquals(configBitSet, checkConfiguration(configRegister));
215
216             // refresh
217             ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
218             testDevice.refresh(mockBridgeHandler, true);
219             inOrder.verify(mockBridgeHandler).readBitSet(eq(testSensorId),
220                     eq(new OwserverDeviceParameter(channelParam)));
221             inOrder.verify(mockThingHandler).postUpdate(eq(channel), stateArgumentCaptor.capture());
222             assertEquals(OnOffType.ON, stateArgumentCaptor.getValue());
223
224             // write
225             if (isOutput) {
226                 ArgumentCaptor<BitSet> bitSetArgumentCaptor = ArgumentCaptor.forClass(BitSet.class);
227                 assertTrue(testDevice.writeChannel(mockBridgeHandler, channel, OnOffType.ON));
228                 inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId),
229                         eq(new OwserverDeviceParameter(channelParam)), bitSetArgumentCaptor.capture());
230                 assertEquals(returnBitSet, bitSetArgumentCaptor.getValue());
231             } else {
232                 assertFalse(testDevice.writeChannel(mockBridgeHandler, channel, OnOffType.ON));
233             }
234
235             inOrder.verifyNoMoreInteractions();
236         } catch (OwException e) {
237             Assert.fail("caught unexpected OwException");
238         }
239     }
240
241     /**
242      * base test case for PWM channels
243      *
244      * @param freqChannel channel name for frequency
245      * @param dutyChannel channel name for duty cycle
246      * @param freqParam owfs parameter for frequency
247      * @param dutyParam owfs parameter for duty cycle
248      * @param registerIndex index for TPM configuration register
249      */
250     private void pwmBaseChannel(String freqChannel, String dutyChannel, String freqParam, String dutyParam,
251             int registerIndex) {
252         Map<String, Object> channelConfig = new HashMap<>();
253         channelConfig.put("prescaler", 5);
254         addChannel(freqChannel, "Number:Frequency", new Configuration(channelConfig));
255         addChannel(dutyChannel, "Number:Dimensionless");
256
257         final BAE0910 testDevice = instantiateDevice();
258         final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
259
260         try {
261             Mockito.when(mockBridgeHandler.checkPresence(testSensorId)).thenReturn(OnOffType.ON);
262             Mockito.when(
263                     mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter(freqParam))))
264                     .thenReturn(new DecimalType(32768));
265             Mockito.when(
266                     mockBridgeHandler.readDecimalType(eq(testSensorId), eq(new OwserverDeviceParameter(dutyParam))))
267                     .thenReturn(new DecimalType(16384));
268
269             testDevice.enableChannel(freqChannel);
270             testDevice.enableChannel(dutyChannel);
271             testDevice.configureChannels(mockBridgeHandler);
272
273             // test configuration
274             assertEquals(bitSet(0, 2), checkConfiguration(registerIndex + 2));
275
276             // refresh
277             ArgumentCaptor<State> stateArgumentCaptor = ArgumentCaptor.forClass(State.class);
278             testDevice.refresh(mockBridgeHandler, true);
279             inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
280                     eq(new OwserverDeviceParameter(freqParam)));
281             inOrder.verify(mockThingHandler).postUpdate(eq(freqChannel), stateArgumentCaptor.capture());
282             assertEquals(new QuantityType<>("15.2587890625 Hz"), stateArgumentCaptor.getValue());
283             inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
284                     eq(new OwserverDeviceParameter(dutyParam)));
285             inOrder.verify(mockThingHandler).postUpdate(eq(dutyChannel), stateArgumentCaptor.capture());
286             assertEquals(new QuantityType<>("50 %"), stateArgumentCaptor.getValue());
287
288             // write
289             ArgumentCaptor<DecimalType> decimalTypeArgumentCaptor = ArgumentCaptor.forClass(DecimalType.class);
290             assertTrue(testDevice.writeChannel(mockBridgeHandler, freqChannel, new QuantityType<>("50000 Hz")));
291             inOrder.verify(mockBridgeHandler).writeDecimalType(eq(testSensorId),
292                     eq(new OwserverDeviceParameter(freqParam)), decimalTypeArgumentCaptor.capture());
293             assertEquals(new DecimalType(10), decimalTypeArgumentCaptor.getValue());
294             testDevice.writeChannel(mockBridgeHandler, dutyChannel, new QuantityType<>("25 %"));
295             inOrder.verify(mockBridgeHandler).readDecimalType(eq(testSensorId),
296                     eq(new OwserverDeviceParameter(freqParam)));
297             inOrder.verify(mockBridgeHandler).writeDecimalType(eq(testSensorId),
298                     eq(new OwserverDeviceParameter(dutyParam)), decimalTypeArgumentCaptor.capture());
299             assertEquals(new DecimalType(8192), decimalTypeArgumentCaptor.getValue());
300
301             inOrder.verifyNoMoreInteractions();
302         } catch (OwException e) {
303             Assert.fail("caught unexpected OwException");
304         }
305     }
306
307     /**
308      * check if all registers are written and return one
309      *
310      * @param registerIndex number of register to return
311      * @return this register's BitSet
312      * @throws OwException
313      */
314     private BitSet checkConfiguration(int registerIndex) throws OwException {
315         ArgumentCaptor<BitSet> configArgumentCaptor = ArgumentCaptor.forClass(BitSet.class);
316         final InOrder inOrder = Mockito.inOrder(mockThingHandler, mockBridgeHandler);
317
318         inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/outc")),
319                 configArgumentCaptor.capture());
320         inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/pioc")),
321                 configArgumentCaptor.capture());
322         inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/adcc")),
323                 configArgumentCaptor.capture());
324         inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/tpm1c")),
325                 configArgumentCaptor.capture());
326         inOrder.verify(mockBridgeHandler).writeBitSet(eq(testSensorId), eq(new OwserverDeviceParameter("/tpm2c")),
327                 configArgumentCaptor.capture());
328         return configArgumentCaptor.getAllValues().get(registerIndex);
329     }
330
331     /**
332      * BitSet with pre-set bits
333      *
334      * @param bits which bits to set
335      * @return the BitSet
336      */
337     private BitSet bitSet(int... bits) {
338         BitSet bitSet = new BitSet(8);
339         Arrays.stream(bits).forEach(b -> bitSet.set(b));
340         return bitSet;
341     }
342 }