mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[knx] Correctly support state sub-types for DPTs (#16337)
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
parent
c9926ccc47
commit
7671f4b9b1
@ -12,9 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.knx.internal.channel;
|
package org.openhab.binding.knx.internal.channel;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.*;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static org.openhab.binding.knx.internal.KNXBindingConstants.CONTROL_CHANNEL_TYPES;
|
import static org.openhab.binding.knx.internal.KNXBindingConstants.*;
|
||||||
import static org.openhab.binding.knx.internal.KNXBindingConstants.GA;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -31,6 +30,7 @@ import org.openhab.binding.knx.internal.dpt.DPTUtil;
|
|||||||
import org.openhab.core.config.core.Configuration;
|
import org.openhab.core.config.core.Configuration;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
import org.openhab.core.types.Type;
|
import org.openhab.core.types.Type;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -121,11 +121,22 @@ public abstract class KNXChannel {
|
|||||||
logger.trace("getCommandSpec checking keys '{}' for command '{}' ({})", gaKeys, command, command.getClass());
|
logger.trace("getCommandSpec checking keys '{}' for command '{}' ({})", gaKeys, command, command.getClass());
|
||||||
for (Map.Entry<String, GroupAddressConfiguration> entry : groupAddressConfigurations.entrySet()) {
|
for (Map.Entry<String, GroupAddressConfiguration> entry : groupAddressConfigurations.entrySet()) {
|
||||||
String dpt = Objects.requireNonNullElse(entry.getValue().getDPT(), getDefaultDPT(entry.getKey()));
|
String dpt = Objects.requireNonNullElse(entry.getValue().getDPT(), getDefaultDPT(entry.getKey()));
|
||||||
Set<Class<? extends Type>> expectedTypeClass = DPTUtil.getAllowedTypes(dpt);
|
Set<Class<? extends Type>> expectedTypeClasses = DPTUtil.getAllowedTypes(dpt);
|
||||||
if (expectedTypeClass.contains(command.getClass())) {
|
// find the first matching type that is assignable from the command
|
||||||
logger.trace("getCommandSpec key '{}' has expectedTypeClass '{}', matching command '{}' and dpt '{}'",
|
for (Class<? extends Type> expectedTypeClass : expectedTypeClasses) {
|
||||||
entry.getKey(), expectedTypeClass, command, dpt);
|
if (expectedTypeClass.equals(command.getClass())) {
|
||||||
return new WriteSpecImpl(entry.getValue(), dpt, command);
|
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!");
|
logger.trace("getCommandSpec no Spec found!");
|
||||||
|
@ -24,6 +24,8 @@ import java.util.Set;
|
|||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openhab.core.config.core.Configuration;
|
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.Channel;
|
||||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||||
import org.openhab.core.types.UnDefType;
|
import org.openhab.core.types.UnDefType;
|
||||||
@ -158,6 +160,18 @@ class KNXChannelTest {
|
|||||||
assertTrue(writeAddresses.contains(new GroupAddress("7/1/9")));
|
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 {
|
private static class MyKNXChannel extends KNXChannel {
|
||||||
public MyKNXChannel(Channel channel) {
|
public MyKNXChannel(Channel channel) {
|
||||||
super(Set.of("key1", "key2"), List.of(UnDefType.class), channel);
|
super(Set.of("key1", "key2"), List.of(UnDefType.class), channel);
|
||||||
|
Loading…
Reference in New Issue
Block a user