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