[knx] Fix dimmer channels (#16364)

* [knx] Fix dimmer channels

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K 2024-02-05 23:15:54 +01:00 committed by GitHub
parent b316096e29
commit 8c0db0a4ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 12 deletions

View 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;
}

View 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);