*/
package org.openhab.binding.knx.internal.channel;
-import static java.util.stream.Collectors.*;
-import static org.openhab.binding.knx.internal.KNXBindingConstants.CONTROL_CHANNEL_TYPES;
-import static org.openhab.binding.knx.internal.KNXBindingConstants.GA;
+import static java.util.stream.Collectors.toList;
+import static org.openhab.binding.knx.internal.KNXBindingConstants.*;
import java.util.HashMap;
import java.util.HashSet;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.types.State;
import org.openhab.core.types.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
logger.trace("getCommandSpec checking keys '{}' for command '{}' ({})", gaKeys, command, command.getClass());
for (Map.Entry<String, GroupAddressConfiguration> entry : groupAddressConfigurations.entrySet()) {
String dpt = Objects.requireNonNullElse(entry.getValue().getDPT(), getDefaultDPT(entry.getKey()));
- Set<Class<? extends Type>> expectedTypeClass = DPTUtil.getAllowedTypes(dpt);
- if (expectedTypeClass.contains(command.getClass())) {
- logger.trace("getCommandSpec key '{}' has expectedTypeClass '{}', matching command '{}' and dpt '{}'",
- entry.getKey(), expectedTypeClass, command, dpt);
- return new WriteSpecImpl(entry.getValue(), dpt, command);
+ 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);
+ }
+ }
+ }
}
}
logger.trace("getCommandSpec no Spec found!");
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
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.thing.Channel;
import org.openhab.core.thing.type.ChannelTypeUID;
import org.openhab.core.types.UnDefType;
assertTrue(writeAddresses.contains(new GroupAddress("7/1/9")));
}
+ @Test
+ void testSubTypeMapping() throws KNXFormatException {
+ Channel channel = Objects.requireNonNull(mock(Channel.class));
+ Configuration configuration = new Configuration(Map.of("key1", "1.001:1/2/3"));
+ when(channel.getChannelTypeUID()).thenReturn(new ChannelTypeUID("a:b:c"));
+ when(channel.getConfiguration()).thenReturn(configuration);
+ when(channel.getAcceptedItemType()).thenReturn(ColorItem.class.getName());
+ MyKNXChannel knxChannel = new MyKNXChannel(channel);
+ assertNotNull(knxChannel.getCommandSpec(new HSBType("0,100,100")));
+ assertEquals(knxChannel.getCommandSpec(new HSBType("0,100,100")).getDPT(), "1.001");
+ }
+
private static class MyKNXChannel extends KNXChannel {
public MyKNXChannel(Channel channel) {
super(Set.of("key1", "key2"), List.of(UnDefType.class), channel);