]> git.basschouten.com Git - openhab-addons.git/commitdiff
[knx] Fix dimmer channels (#16364)
authorJ-N-K <github@klug.nrw>
Mon, 5 Feb 2024 22:15:54 +0000 (23:15 +0100)
committerGitHub <noreply@github.com>
Mon, 5 Feb 2024 22:15:54 +0000 (23:15 +0100)
* [knx] Fix dimmer channels

Signed-off-by: Jan N. Klug <github@klug.nrw>
bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/channel/KNXChannel.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/channel/KNXChannelTest.java

index 8db0dc22fd4b8cf335c7093e673b3459aa28911d..407fc56a10977aa8cc83efaf08ce523a0baf45c8 100644 (file)
@@ -123,23 +123,31 @@ public abstract class KNXChannel {
             String dpt = Objects.requireNonNullElse(entry.getValue().getDPT(), getDefaultDPT(entry.getKey()));
             Set<Class<? extends Type>> expectedTypeClasses = DPTUtil.getAllowedTypes(dpt);
             // find the first matching type that is assignable from the command
-            for (Class<? extends Type> expectedTypeClass : expectedTypeClasses) {
-                if (expectedTypeClass.equals(command.getClass())) {
-                    logger.trace("getCommandSpec command class matches expected type class");
-                    return new WriteSpecImpl(entry.getValue(), dpt, command);
-                } else if (command instanceof State state && State.class.isAssignableFrom(expectedTypeClass)) {
-                    if (state.as(expectedTypeClass.asSubclass(State.class)) != null) {
-                        logger.trace("getCommandSpec command class is a sub-class of the expected type class");
-                        Class<? extends State> expectedTypeAsStateClass = expectedTypeClass.asSubclass(State.class);
-                        State convertedState = state.as(expectedTypeAsStateClass);
-                        if (convertedState != null) {
-                            return new WriteSpecImpl(entry.getValue(), dpt, convertedState);
+            if (expectedTypeClasses.contains(command.getClass())) {
+                logger.trace(
+                        "getCommandSpec key '{}' has one of the expectedTypeClasses '{}', matching command '{}' and dpt '{}'",
+                        entry.getKey(), expectedTypeClasses, command, dpt);
+                return new WriteSpecImpl(entry.getValue(), dpt, command);
+            } else {
+                for (Class<? extends Type> expectedTypeClass : expectedTypeClasses) {
+                    if (command instanceof State state && State.class.isAssignableFrom(expectedTypeClass)) {
+                        if (state.as(expectedTypeClass.asSubclass(State.class)) != null) {
+                            logger.trace(
+                                    "getCommandSpec command class '{}' is a sub-class of the expectedTypeClass '{}' for key '{}'",
+                                    command.getClass(), expectedTypeClass, entry.getKey());
+                            Class<? extends State> expectedTypeAsStateClass = expectedTypeClass.asSubclass(State.class);
+                            State convertedState = state.as(expectedTypeAsStateClass);
+                            if (convertedState != null) {
+                                return new WriteSpecImpl(entry.getValue(), dpt, convertedState);
+                            }
                         }
                     }
                 }
             }
         }
-        logger.trace("getCommandSpec no Spec found!");
+        logger.trace(
+                "getCommandSpec could not match command class '{}' with expectedTypeClasses for any of the checked keys '{}', discarding command",
+                command.getClass(), gaKeys);
         return null;
     }
 
index a943d4288e080c57852cbe292fd381909ff7eecc..854b08eb04d13e8adb43dd42d82f288121554904 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.knx.internal.channel;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -23,11 +25,16 @@ import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.junit.jupiter.api.Test;
+import org.openhab.binding.knx.internal.KNXBindingConstants;
+import org.openhab.binding.knx.internal.client.OutboundSpec;
+import org.openhab.binding.knx.internal.dpt.ValueEncoder;
 import org.openhab.core.config.core.Configuration;
 import org.openhab.core.library.items.ColorItem;
 import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.PercentType;
 import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.type.ChannelTypeUID;
+import org.openhab.core.types.Command;
 import org.openhab.core.types.UnDefType;
 
 import tuwien.auto.calimero.GroupAddress;
@@ -172,6 +179,26 @@ class KNXChannelTest {
         assertEquals(knxChannel.getCommandSpec(new HSBType("0,100,100")).getDPT(), "1.001");
     }
 
+    @Test
+    void test5001PercentType() throws KNXFormatException {
+        Configuration configuration = new Configuration(Map.of("switch", "1.001:1/2/1", "position", "5.001:1/2/2"));
+        Channel channel = Objects.requireNonNull(mock(Channel.class));
+        when(channel.getChannelTypeUID())
+                .thenReturn(new ChannelTypeUID(KNXBindingConstants.BINDING_ID, KNXBindingConstants.CHANNEL_DIMMER));
+        when(channel.getConfiguration()).thenReturn(configuration);
+
+        KNXChannel knxChannel = KNXChannelFactory.createKnxChannel(channel);
+        assertThat(knxChannel, instanceOf(TypeDimmer.class));
+
+        Command command = new PercentType("100");
+        OutboundSpec outboundSpec = knxChannel.getCommandSpec(command);
+        assertThat(outboundSpec, is(notNullValue()));
+
+        String mappedValue = ValueEncoder.encode(outboundSpec.getValue(), outboundSpec.getDPT());
+        assertThat(mappedValue, is("100"));
+        assertThat(outboundSpec.getValue(), is(instanceOf(PercentType.class)));
+    }
+
     private static class MyKNXChannel extends KNXChannel {
         public MyKNXChannel(Channel channel) {
             super(Set.of("key1", "key2"), List.of(UnDefType.class), channel);