]> git.basschouten.com Git - openhab-addons.git/blob
00f702c3adf095dab6cf59c252dba083a2735a58
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.knx.internal.channel;
14
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.Matchers.*;
17 import static org.junit.jupiter.api.Assertions.*;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.when;
20
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.junit.jupiter.api.Test;
28 import org.openhab.binding.knx.internal.KNXBindingConstants;
29 import org.openhab.binding.knx.internal.client.OutboundSpec;
30 import org.openhab.binding.knx.internal.dpt.ValueEncoder;
31 import org.openhab.core.config.core.Configuration;
32 import org.openhab.core.library.items.ColorItem;
33 import org.openhab.core.library.types.HSBType;
34 import org.openhab.core.library.types.OnOffType;
35 import org.openhab.core.library.types.PercentType;
36 import org.openhab.core.thing.Channel;
37 import org.openhab.core.thing.type.ChannelTypeUID;
38 import org.openhab.core.types.Command;
39 import org.openhab.core.types.UnDefType;
40
41 import tuwien.auto.calimero.GroupAddress;
42 import tuwien.auto.calimero.KNXFormatException;
43
44 /**
45  *
46  * @author Simon Kaufmann - Initial contribution
47  *
48  */
49 @NonNullByDefault
50 class KNXChannelTest {
51
52     @Test
53     public void invalidFails() {
54         GroupAddressConfiguration res = GroupAddressConfiguration.parse("5.001:<1/3/22+0/3/22+<0/8/15");
55         assertNull(res);
56     }
57
58     @Test
59     void testParseWithDptMultipleWithRead() throws KNXFormatException {
60         GroupAddressConfiguration res = GroupAddressConfiguration.parse("5.001:<1/3/22+0/3/22+<0/7/15");
61
62         if (res == null) {
63             fail();
64             return;
65         }
66
67         assertEquals("5.001", res.getDPT());
68         assertEquals(new GroupAddress("1/3/22"), res.getMainGA());
69         assertTrue(res.getReadGAs().contains(res.getMainGA()));
70         assertEquals(3, res.getListenGAs().size());
71         assertEquals(2, res.getReadGAs().size());
72     }
73
74     @Test
75     void testParseWithDptMultipleWithoutRead() throws KNXFormatException {
76         GroupAddressConfiguration res = GroupAddressConfiguration.parse("5.001:1/3/22+0/3/22+0/7/15");
77
78         if (res == null) {
79             fail();
80             return;
81         }
82
83         assertEquals("5.001", res.getDPT());
84         assertEquals(new GroupAddress("1/3/22"), res.getMainGA());
85         assertFalse(res.getReadGAs().contains(res.getMainGA()));
86         assertEquals(3, res.getListenGAs().size());
87         assertEquals(0, res.getReadGAs().size());
88     }
89
90     @Test
91     void testParseWithoutDptSingleWithoutRead() throws KNXFormatException {
92         GroupAddressConfiguration res = GroupAddressConfiguration.parse("1/3/22");
93
94         if (res == null) {
95             fail();
96             return;
97         }
98
99         assertNull(res.getDPT());
100         assertEquals(new GroupAddress("1/3/22"), res.getMainGA());
101         assertFalse(res.getReadGAs().contains(res.getMainGA()));
102         assertEquals(1, res.getListenGAs().size());
103         assertEquals(0, res.getReadGAs().size());
104     }
105
106     @Test
107     void testParseWithoutDptSingleWithRead() throws KNXFormatException {
108         GroupAddressConfiguration res = GroupAddressConfiguration.parse("<1/3/22");
109
110         if (res == null) {
111             fail();
112             return;
113         }
114
115         assertNull(res.getDPT());
116         assertEquals(new GroupAddress("1/3/22"), res.getMainGA());
117         assertTrue(res.getReadGAs().contains(res.getMainGA()));
118         assertEquals(1, res.getListenGAs().size());
119         assertEquals(1, res.getReadGAs().size());
120     }
121
122     @Test
123     void testParseTwoLevel() throws KNXFormatException {
124         GroupAddressConfiguration res = GroupAddressConfiguration.parse("5.001:<3/1024+<4/1025");
125
126         if (res == null) {
127             fail();
128             return;
129         }
130
131         assertEquals(new GroupAddress("3/1024"), res.getMainGA());
132         assertTrue(res.getReadGAs().contains(res.getMainGA()));
133         assertEquals(2, res.getListenGAs().size());
134         assertEquals(2, res.getReadGAs().size());
135     }
136
137     @Test
138     void testParseFreeLevel() throws KNXFormatException {
139         GroupAddressConfiguration res = GroupAddressConfiguration.parse("5.001:<4610+<4611");
140
141         if (res == null) {
142             fail();
143             return;
144         }
145
146         assertEquals(new GroupAddress("4610"), res.getMainGA());
147         assertEquals(2, res.getListenGAs().size());
148         assertEquals(2, res.getReadGAs().size());
149     }
150
151     @Test
152     public void testChannelGaParsing() throws KNXFormatException {
153         Channel channel = Objects.requireNonNull(mock(Channel.class));
154         Configuration configuration = new Configuration(
155                 Map.of("key1", "5.001:<1/2/3+4/5/6+1/5/6", "key2", "1.001:7/1/9+1/1/2"));
156         when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("a:b:c"));
157         when(channel.getConfiguration()).thenReturn(configuration);
158         when(channel.getAcceptedItemType()).thenReturn("none");
159
160         MyKNXChannel knxChannel = new MyKNXChannel(channel);
161
162         List<GroupAddress> listenAddresses = knxChannel.getAllGroupAddresses();
163         assertEquals(5, listenAddresses.size());
164         // we don't check the content since parsing has been checked before and the quantity is correct
165         List<GroupAddress> writeAddresses = knxChannel.getWriteAddresses();
166         assertEquals(2, writeAddresses.size());
167         assertTrue(writeAddresses.contains(new GroupAddress("1/2/3")));
168         assertTrue(writeAddresses.contains(new GroupAddress("7/1/9")));
169     }
170
171     @Test
172     void testSubTypeMapping() throws KNXFormatException {
173         Channel channel = Objects.requireNonNull(mock(Channel.class));
174         Configuration configuration = new Configuration(Map.of("key1", "1.001:1/2/3"));
175         when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("a:b:c"));
176         when(channel.getConfiguration()).thenReturn(configuration);
177         when(channel.getAcceptedItemType()).thenReturn(ColorItem.class.getName());
178         MyKNXChannel knxChannel = new MyKNXChannel(channel);
179         assertNotNull(knxChannel.getCommandSpec(new HSBType("0,100,100")));
180         @Nullable
181         OutboundSpec outboundSpec = knxChannel.getCommandSpec(new HSBType("0,100,100"));
182         assertNotNull(outboundSpec);
183         assertEquals(outboundSpec.getDPT(), "1.001");
184     }
185
186     @Test
187     void test5001PercentType() throws KNXFormatException {
188         Configuration configuration = new Configuration(Map.of("switch", "1.001:1/2/1", "position", "5.001:1/2/2"));
189         Channel channel = Objects.requireNonNull(mock(Channel.class));
190         when(channel.getChannelTypeUID())
191                 .thenReturn(new ChannelTypeUID(KNXBindingConstants.BINDING_ID, KNXBindingConstants.CHANNEL_DIMMER));
192         when(channel.getConfiguration()).thenReturn(configuration);
193
194         KNXChannel knxChannel = KNXChannelFactory.createKnxChannel(channel);
195         assertThat(knxChannel, instanceOf(TypeDimmer.class));
196
197         Command command = new PercentType("90");
198         @Nullable
199         OutboundSpec outboundSpec = knxChannel.getCommandSpec(command);
200         assertThat(outboundSpec, is(notNullValue()));
201         assertThat(outboundSpec.getGroupAddress(), is(new GroupAddress("1/2/2")));
202
203         String mappedValue = ValueEncoder.encode(outboundSpec.getValue(), outboundSpec.getDPT());
204         assertThat(mappedValue, is("90"));
205         assertThat(outboundSpec.getValue(), is(instanceOf(PercentType.class)));
206     }
207
208     @Test
209     void test1001ToDimmerChannel() throws KNXFormatException {
210         Configuration configuration = new Configuration(Map.of("switch", "1.001:1/2/1", "position", "5.001:1/2/2"));
211         Channel channel = Objects.requireNonNull(mock(Channel.class));
212         when(channel.getChannelTypeUID())
213                 .thenReturn(new ChannelTypeUID(KNXBindingConstants.BINDING_ID, KNXBindingConstants.CHANNEL_DIMMER));
214         when(channel.getConfiguration()).thenReturn(configuration);
215
216         KNXChannel knxChannel = KNXChannelFactory.createKnxChannel(channel);
217         assertThat(knxChannel, instanceOf(TypeDimmer.class));
218
219         Command command = OnOffType.ON;
220         OutboundSpec outboundSpec = knxChannel.getCommandSpec(command);
221         assertThat(outboundSpec, is(notNullValue()));
222         assertThat(outboundSpec.getGroupAddress(), is(new GroupAddress("1/2/1")));
223
224         String mappedValue = ValueEncoder.encode(outboundSpec.getValue(), outboundSpec.getDPT());
225         assertThat(mappedValue, is("on"));
226         assertThat(outboundSpec.getValue(), is(instanceOf(OnOffType.class)));
227     }
228
229     private static class MyKNXChannel extends KNXChannel {
230         public MyKNXChannel(Channel channel) {
231             super(List.of("key1", "key2"), List.of(UnDefType.class), channel);
232         }
233
234         @Override
235         protected String getDefaultDPT(String gaConfigKey) {
236             return "";
237         }
238     }
239 }