[ism8] Allow linking switch-r to Contact items (#17742)

* [ism8] Allow linking switch-... to Contact items

Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
This commit is contained in:
Holger Friedrich 2024-11-30 22:40:32 +01:00 committed by GitHub
parent 3187b0110f
commit 4ed9474bdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 11 deletions

View File

@ -81,6 +81,9 @@ For the moment, the following data types are implemented:
Date and Time types used by for CWL Excellent and CWL2 are currently not supported by the ISM8 add-on. Date and Time types used by for CWL Excellent and CWL2 are currently not supported by the ISM8 add-on.
*Attention:* Due to a bug in the original implementation, the states for DPT 1.009 are inverted (i.e., `1` is mapped to `OPEN` instead of `CLOSE`).
A change would break all existing installations and is therefore not implemented.
## Full Example ## Full Example
### ism8.things ### ism8.things

View File

@ -25,6 +25,7 @@ import javax.measure.quantity.Temperature;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.ism8.server.IDataPoint; import org.openhab.binding.ism8.server.IDataPoint;
import org.openhab.core.library.dimension.VolumetricFlowRate; import org.openhab.core.library.dimension.VolumetricFlowRate;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.SIUnits;
@ -71,8 +72,10 @@ public final class Ism8DomainMap {
return new QuantityType<Dimensionless>((Double) value, Units.PERCENT); return new QuantityType<Dimensionless>((Double) value, Units.PERCENT);
} else if (Units.ONE.equals(unit)) { } else if (Units.ONE.equals(unit)) {
return new QuantityType<Dimensionless>((Double) value, Units.ONE); return new QuantityType<Dimensionless>((Double) value, Units.ONE);
} else if (value instanceof Boolean) { } else if (value instanceof Boolean b) {
return OnOffType.from((boolean) value); // DecimalType is compatible with Switch and Contact items, OH mapping is 0-off-closed and 1-on-open;
// note that this is opposite to definition of KNX DPT 1.009
return b ? DecimalType.valueOf("1") : DecimalType.valueOf("0");
} else if (value instanceof Byte) { } else if (value instanceof Byte) {
return new QuantityType<Dimensionless>((byte) value, Units.ONE); return new QuantityType<Dimensionless>((byte) value, Units.ONE);
} else if (value instanceof Integer) { } else if (value instanceof Integer) {

View File

@ -55,7 +55,8 @@ public class DataPointBool extends DataPointBase<@Nullable Boolean> {
@Override @Override
protected byte[] convertWriteValue(Object value) { protected byte[] convertWriteValue(Object value) {
String valueText = value.toString().toLowerCase(); String valueText = value.toString().toLowerCase();
if ("true".equalsIgnoreCase(valueText) || "1".equalsIgnoreCase(valueText) || "ON".equalsIgnoreCase(valueText)) { if ("true".equalsIgnoreCase(valueText) || "1".equalsIgnoreCase(valueText) || "ON".equalsIgnoreCase(valueText)
|| "OPEN".equalsIgnoreCase(valueText)) {
this.setValue(true); this.setValue(true);
return new byte[] { 0x01 }; return new byte[] { 0x01 };
} }

View File

@ -12,6 +12,7 @@
*/ */
package org.openhab.binding.ism8.internal; package org.openhab.binding.ism8.internal;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.openhab.binding.ism8.internal.Ism8BindingConstants.*; import static org.openhab.binding.ism8.internal.Ism8BindingConstants.*;
@ -31,7 +32,9 @@ import org.openhab.binding.ism8.server.DataPointChangedEvent;
import org.openhab.binding.ism8.server.DataPointValue; import org.openhab.binding.ism8.server.DataPointValue;
import org.openhab.binding.ism8.server.IDataPoint; import org.openhab.binding.ism8.server.IDataPoint;
import org.openhab.core.config.core.Configuration; import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units; import org.openhab.core.library.unit.Units;
@ -57,6 +60,7 @@ public class Ism8HandlerTest {
private @NonNullByDefault({}) Ism8Handler thingHandler; private @NonNullByDefault({}) Ism8Handler thingHandler;
private ThingUID thingUID = new ThingUID(BINDING_ID, "ism8server"); private ThingUID thingUID = new ThingUID(BINDING_ID, "ism8server");
private ChannelUID channel1001 = new ChannelUID(thingUID, "switch1"); private ChannelUID channel1001 = new ChannelUID(thingUID, "switch1");
private ChannelUID channel1001c = new ChannelUID(thingUID, "contact1");
private ChannelUID channel9001 = new ChannelUID(thingUID, "tempC"); private ChannelUID channel9001 = new ChannelUID(thingUID, "tempC");
private ChannelUID channel9002 = new ChannelUID(thingUID, "tempD"); private ChannelUID channel9002 = new ChannelUID(thingUID, "tempD");
private ChannelUID channel20001 = new ChannelUID(thingUID, "mode1"); private ChannelUID channel20001 = new ChannelUID(thingUID, "mode1");
@ -72,6 +76,8 @@ public class Ism8HandlerTest {
.withConfiguration(createChannelConfig("4", "9.001")).build()) .withConfiguration(createChannelConfig("4", "9.001")).build())
.withChannel(ChannelBuilder.create(channel1001, "Switch") .withChannel(ChannelBuilder.create(channel1001, "Switch")
.withConfiguration(createChannelConfig("9", "1.001")).build()) .withConfiguration(createChannelConfig("9", "1.001")).build())
.withChannel(ChannelBuilder.create(channel1001c, "Contact")
.withConfiguration(createChannelConfig("8", "1.001")).build())
.withChannel(ChannelBuilder.create(channel20001, "Switch") .withChannel(ChannelBuilder.create(channel20001, "Switch")
.withConfiguration(createChannelConfig("2", "20.001")).build()) .withConfiguration(createChannelConfig("2", "20.001")).build())
.build(); .build();
@ -99,7 +105,24 @@ public class Ism8HandlerTest {
thingHandler.dataPointChanged(event); thingHandler.dataPointChanged(event);
// assert // assert
Mockito.verify(thingHandlerCallback).stateUpdated(eq(channel1001), eq(OnOffType.from(false))); Mockito.verify(thingHandlerCallback).stateUpdated(eq(channel1001), eq(DecimalType.valueOf("0")));
assertEquals(OnOffType.from(false), OnOffType.from(DecimalType.valueOf("0").toString()));
}
// @Test
public void process1001cMessageAndUpdateChannel() {
// arrange
IDataPoint dataPoint = new DataPointBool(8, "1.001", "Datapoint_1.001");
dataPoint.processData(HexUtils.hexToBytes("0008030100"));
DataPointChangedEvent event = new DataPointChangedEvent(new Object(), dataPoint);
thingHandler.setCallback(thingHandlerCallback);
// act
thingHandler.dataPointChanged(event);
// assert
Mockito.verify(thingHandlerCallback).stateUpdated(eq(channel1001c), eq(DecimalType.valueOf("0")));
assertEquals(OpenClosedType.CLOSED.as(DecimalType.class), DecimalType.valueOf("0"));
} }
@Test @Test

View File

@ -29,7 +29,9 @@ import org.openhab.binding.ism8.server.DataPointLongValue;
import org.openhab.binding.ism8.server.DataPointScaling; import org.openhab.binding.ism8.server.DataPointScaling;
import org.openhab.binding.ism8.server.DataPointValue; import org.openhab.binding.ism8.server.DataPointValue;
import org.openhab.binding.ism8.server.IDataPoint; import org.openhab.binding.ism8.server.IDataPoint;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.ImperialUnits;
import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.SIUnits;
@ -118,7 +120,8 @@ public class Ism8DomainMapTest {
State result = Ism8DomainMap.toOpenHABState(dataPoint); State result = Ism8DomainMap.toOpenHABState(dataPoint);
// assert // assert
assertEquals(OnOffType.from(false), result); assertEquals(DecimalType.valueOf("0"), result);
assertEquals(OnOffType.from(false), OnOffType.from(DecimalType.valueOf("0").toString()));
} }
{ {
// arrange // arrange
@ -129,7 +132,8 @@ public class Ism8DomainMapTest {
State result = Ism8DomainMap.toOpenHABState(dataPoint); State result = Ism8DomainMap.toOpenHABState(dataPoint);
// assert // assert
assertEquals(OnOffType.from(true), result); assertEquals(DecimalType.valueOf("1"), result);
assertEquals(OnOffType.from(true), OnOffType.from(DecimalType.valueOf("1").toString()));
} }
{ {
// arrange // arrange
@ -140,7 +144,8 @@ public class Ism8DomainMapTest {
State result = Ism8DomainMap.toOpenHABState(dataPoint); State result = Ism8DomainMap.toOpenHABState(dataPoint);
// assert // assert
assertEquals(OnOffType.from(true), result); assertEquals(DecimalType.valueOf("1"), result);
assertEquals(OnOffType.from(true), OnOffType.from(DecimalType.valueOf("1").toString()));
} }
{ {
// arrange // arrange
@ -151,7 +156,8 @@ public class Ism8DomainMapTest {
State result = Ism8DomainMap.toOpenHABState(dataPoint); State result = Ism8DomainMap.toOpenHABState(dataPoint);
// assert // assert
assertEquals(OnOffType.from(true), result); assertEquals(DecimalType.valueOf("1"), result);
assertEquals(OnOffType.from(true), OnOffType.from(DecimalType.valueOf("1").toString()));
} }
{ {
// arrange // arrange
@ -162,9 +168,11 @@ public class Ism8DomainMapTest {
State result = Ism8DomainMap.toOpenHABState(dataPoint); State result = Ism8DomainMap.toOpenHABState(dataPoint);
// assert // assert
assertEquals(OnOffType.from(true), result); assertEquals(DecimalType.valueOf("1"), result);
// TODO: check if OpenClosedType is appropriate assertEquals(OnOffType.ON, OnOffType.from(DecimalType.valueOf("1").toString()));
// assertEquals(OpenClosedType.valueOf("OPEN"), result); // DecimalType is compatible with Switch and Contact items, OH mapping is 0-off-closed and 1-on-open;
// note that this is opposite to definition of KNX DPT 1.009
assertEquals(OpenClosedType.CLOSED.as(DecimalType.class), DecimalType.valueOf("0"));
} }
} }