mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[knx] Allow receiving DPT 235.001 (#16094)
* [knx] Allow receiving DPT 235.001 Composed type not yet supported by Calimero, thus only receiving data is implemented. Configure DPT 235.001 to receive ActiveEnergy. Configure DPT 235.61001 to receive Tariff information. Fixes #15159 Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
This commit is contained in:
parent
3ea1451050
commit
e62bcf5db4
@ -267,6 +267,18 @@ With `*-control` channels, the state is not owned by any device on the KNX bus,
|
||||
The element `dpt` is highly recommended and may change to a mandatory element in future versions.
|
||||
If omitted, the corresponding default value will be used (see the channel descriptions above).
|
||||
|
||||
## Special DPTs
|
||||
|
||||
OpenHAB supports all DPTs supported by the corresponding release of Calimero library.
|
||||
|
||||
Additional DPTs have been introduced to add functionality:
|
||||
|
||||
| DPT | Description | Remark |
|
||||
|---------------|-------------------------------------------------------------|------------|
|
||||
| DPT 232.60000 | DPT 232.600 with HSB instead of RGB data (see below) | read/write |
|
||||
| DPT 235.001 | Composed DPT 235.001, first element ActiveEnergy (Wh) | read only |
|
||||
| DPT 235.61001 | Composed DPT 235.001, second element Tariff (plain number) | read only |
|
||||
|
||||
## KNX Secure
|
||||
|
||||
> NOTE: Support for KNX Secure is partly implemented for openHAB and should be considered as experimental.
|
||||
|
@ -84,6 +84,7 @@ public class DPTUtil {
|
||||
Map.entry("29", Set.of(QuantityType.class, DecimalType.class)), //
|
||||
Map.entry("229", Set.of(DecimalType.class)), //
|
||||
Map.entry("232", Set.of(HSBType.class)), //
|
||||
Map.entry("235", Set.of(QuantityType.class, DecimalType.class)), //
|
||||
Map.entry("242", Set.of(HSBType.class)), //
|
||||
Map.entry("243", Set.of(StringType.class)), //
|
||||
Map.entry("249", Set.of(StringType.class)), //
|
||||
|
@ -81,6 +81,28 @@ public class ValueDecoder {
|
||||
public static final Pattern XYY_PATTERN = Pattern
|
||||
.compile("(?:\\((?<x>\\d+(?:[,.]\\d+)?) (?<y>\\d+(?:[,.]\\d+)?)\\))?\\s*(?:(?<Y>\\d+(?:[,.]\\d+)?)\\s%)?");
|
||||
|
||||
private static boolean check235001(byte[] data) throws KNXException {
|
||||
if (data.length != 6) {
|
||||
throw new KNXFormatException("DPT235 broken frame");
|
||||
}
|
||||
if ((data[5] & 2) == 0) {
|
||||
LOGGER.trace("DPT235.001 w/o ActiveEnergy ignored");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean check23561001(byte[] data) throws KNXException {
|
||||
if (data.length != 6) {
|
||||
throw new KNXFormatException("DPT235 broken frame");
|
||||
}
|
||||
if ((data[5] & 1) == 0) {
|
||||
LOGGER.trace("DPT235.61001 w/o Tariff ignored");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the raw value received to the corresponding openHAB value
|
||||
*
|
||||
@ -91,18 +113,46 @@ public class ValueDecoder {
|
||||
*/
|
||||
public static @Nullable Type decode(String dptId, byte[] data, Class<? extends Type> preferredType) {
|
||||
try {
|
||||
DPTXlator translator = TranslatorTypes.createTranslator(0,
|
||||
DPTUtil.NORMALIZED_DPT.getOrDefault(dptId, dptId));
|
||||
translator.setData(data);
|
||||
String value = translator.getValue();
|
||||
|
||||
String value = "";
|
||||
String translatorDptId = dptId;
|
||||
DPTXlator translator;
|
||||
try {
|
||||
translator = TranslatorTypes.createTranslator(0, DPTUtil.NORMALIZED_DPT.getOrDefault(dptId, dptId));
|
||||
translator.setData(data);
|
||||
value = translator.getValue();
|
||||
translatorDptId = translator.getType().getID();
|
||||
} catch (KNXException e) {
|
||||
// special handling for decoding DPTs not yet supported by Calimero
|
||||
if ("235.001".equals(dptId)) {
|
||||
if (!check235001(data)) {
|
||||
return null;
|
||||
}
|
||||
translator = TranslatorTypes.createTranslator(0, "13.010");
|
||||
translator.setData(data);
|
||||
value = translator.getValue();
|
||||
dptId = "13.010";
|
||||
translatorDptId = dptId;
|
||||
} else if ("235.61001".equals(dptId)) {
|
||||
if (!check23561001(data)) {
|
||||
return null;
|
||||
}
|
||||
translator = TranslatorTypes.createTranslator(0, "5.006");
|
||||
translator.setData(new byte[] { data[4] });
|
||||
value = translator.getValue();
|
||||
dptId = "5.006";
|
||||
translatorDptId = dptId;
|
||||
} else {
|
||||
// no known special case, handle unknown translator outer try block
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
String id = dptId; // prefer using the user-supplied DPT
|
||||
|
||||
Matcher m = DPTUtil.DPT_PATTERN.matcher(id);
|
||||
if (!m.matches() || m.groupCount() != 2) {
|
||||
LOGGER.trace("User-Supplied DPT '{}' did not match for sub-type, using DPT returned from Translator",
|
||||
id);
|
||||
id = translator.getType().getID();
|
||||
id = translatorDptId;
|
||||
m = DPTUtil.DPT_PATTERN.matcher(id);
|
||||
if (!m.matches() || m.groupCount() != 2) {
|
||||
LOGGER.warn("Couldn't identify main/sub number in dptID '{}'", id);
|
||||
|
@ -330,6 +330,30 @@ class DPTTest {
|
||||
assertEquals(encoded, "r:" + data[0] + " g:" + data[1] + " b:" + data[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dpt235Decoder() {
|
||||
byte[] noActiveEnergy = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
|
||||
(byte) 0xfd };
|
||||
assertNull(ValueDecoder.decode("235.001", noActiveEnergy, QuantityType.class));
|
||||
|
||||
byte[] noTariff = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xfe };
|
||||
assertNull(ValueDecoder.decode("235.61001", noTariff, DecimalType.class));
|
||||
|
||||
byte[] activeEnergy = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x03, (byte) 0xff, (byte) 0x0a, (byte) 0x02 };
|
||||
assertEquals(new QuantityType<>("1023 Wh"), ValueDecoder.decode("235.001", activeEnergy, QuantityType.class));
|
||||
|
||||
byte[] activeTariff = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x03, (byte) 0xff, (byte) 0x0a, (byte) 0x01 };
|
||||
assertEquals(new DecimalType("10"), ValueDecoder.decode("235.61001", activeTariff, DecimalType.class));
|
||||
|
||||
byte[] activeAll = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x03, (byte) 0xff, (byte) 0x0a, (byte) 0x03 };
|
||||
assertEquals(new QuantityType<>("1023 Wh"), ValueDecoder.decode("235.001", activeAll, QuantityType.class));
|
||||
assertEquals(new DecimalType("10"), ValueDecoder.decode("235.61001", activeAll, DecimalType.class));
|
||||
|
||||
byte[] negativeEnergy = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
|
||||
(byte) 0x02 };
|
||||
assertEquals(new QuantityType<>("-1 Wh"), ValueDecoder.decode("235.001", negativeEnergy, QuantityType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dpt251White() {
|
||||
// input data: color white
|
||||
|
Loading…
Reference in New Issue
Block a user