diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDataPoints.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDataPoints.java index bde36cc5d..652a3047c 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDataPoints.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDataPoints.java @@ -83,8 +83,7 @@ public class RdsDataPoints { * execute an HTTP GET command on the remote cloud server to retrieve the JSON * response from the given urlString */ - protected static String httpGenericGetJson(String apiKey, String token, String urlString) - throws RdsCloudException, IOException { + protected static String httpGenericGetJson(String apiKey, String token, String urlString) throws IOException { /* * NOTE: this class uses JAVAX HttpsURLConnection library instead of the * preferred JETTY library; the reason is that JETTY does not allow sending the @@ -196,7 +195,7 @@ public class RdsDataPoints { } @Nullable String pointId = indexClassToId.get(pointClass); - if (pointId != null) { + if (pointId != null && !pointId.isEmpty()) { return pointId; } throw new RdsCloudException(String.format("no pointId to match pointClass \"%s\"", pointClass)); @@ -250,10 +249,12 @@ public class RdsDataPoints { Set set = new HashSet<>(); String pointId; - for (ChannelMap chan : CHAN_MAP) { - pointId = pointClassToId(chan.clazz); - if (!pointId.isEmpty()) { + for (ChannelMap channel : CHAN_MAP) { + try { + pointId = pointClassToId(channel.clazz); set.add(String.format("\"%s\"", pointId)); + } catch (RdsCloudException e) { + logger.debug("{} \"{}\" not implemented; don't include in request", channel.id, channel.clazz); } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandler.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandler.java index 51756a38e..1c4ffdac0 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandler.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandler.java @@ -38,6 +38,7 @@ import org.openhab.core.thing.binding.BridgeHandler; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,9 +47,9 @@ import com.google.gson.JsonParseException; /** * The {@link RdsHandler} is the OpenHab Handler for Siemens RDS smart * thermostats - * + * * @author Andrew Fiddian-Green - Initial contribution - * + * */ @NonNullByDefault public class RdsHandler extends BaseThingHandler { @@ -229,7 +230,15 @@ public class RdsHandler extends BaseThingHandler { continue; } - BasePoint point = points.getPointByClass(channel.clazz); + BasePoint point; + try { + point = points.getPointByClass(channel.clazz); + } catch (RdsCloudException e) { + logger.debug("{} \"{}\" not implemented; set state to UNDEF", channel.id, channel.clazz); + updateState(channel.id, UnDefType.UNDEF); + continue; + } + State state = null; switch (channel.id) { diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java index 476cb0afe..98cde9a51 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.siemensrds.points; +import javax.measure.MetricPrefix; import javax.measure.Unit; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -43,6 +44,12 @@ public abstract class BasePoint { public static final String DEGREES_KELVIN = "K"; public static final String PERCENT_RELATIVE_HUMIDITY = "%r.H."; + private static final String PARTS_PER_MILLION = "ppm"; + private static final String MILLI_SECOND = "ms"; + private static final String MINUTE = "min"; + private static final String HOUR = "h"; + private static final String AMPERE = "A"; + public static final int UNDEFINED_VALUE = -1; @SerializedName("rep") @@ -68,7 +75,7 @@ public abstract class BasePoint { @SerializedName("presentPriority") protected int presentPriority; - private String @Nullable [] enumVals; + private String[] enumVals = {}; private boolean enumParsed = false; protected boolean isEnum = false; @@ -79,7 +86,8 @@ public abstract class BasePoint { if (!enumParsed) { String descr = this.descr; if (descr != null && descr.contains("*")) { - enumVals = descr.split("\\*"); + String[] values = descr.split("\\*"); + enumVals = values; isEnum = true; } } @@ -107,8 +115,7 @@ public abstract class BasePoint { public State getEnum() { if (isEnum()) { int index = asInt(); - String[] enumVals = this.enumVals; - if (index >= 0 && enumVals != null && index < enumVals.length) { + if (index >= 0 && index < enumVals.length) { return new StringType(enumVals[index]); } } @@ -127,8 +134,7 @@ public abstract class BasePoint { */ public Unit getUnit() { /* - * determine the Units of Measure if available; note that other possible units - * (Ampere, hours, milliseconds, minutes) are currently not implemented + * determine the Units of Measure if available */ String descr = this.descr; if (descr != null) { @@ -145,6 +151,21 @@ public abstract class BasePoint { case PERCENT_RELATIVE_HUMIDITY: { return Units.PERCENT; } + case AMPERE: { + return Units.AMPERE; + } + case HOUR: { + return Units.HOUR; + } + case MINUTE: { + return Units.MINUTE; + } + case MILLI_SECOND: { + return MetricPrefix.MILLI(Units.SECOND); + } + case PARTS_PER_MILLION: { + return Units.PARTS_PER_MILLION; + } } } return Units.ONE; @@ -155,12 +176,9 @@ public abstract class BasePoint { */ public String commandJson(String newVal) { if (isEnum()) { - String[] enumVals = this.enumVals; - if (enumVals != null) { - for (int index = 0; index < enumVals.length; index++) { - if (enumVals[index].equals(newVal)) { - return String.format("{\"value\":%d}", index); - } + for (int index = 0; index < enumVals.length; index++) { + if (enumVals[index].equals(newVal)) { + return String.format("{\"value\":%d}", index); } } } diff --git a/bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/RdsTestData.java b/bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/TestRdsData.java similarity index 87% rename from bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/RdsTestData.java rename to bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/TestRdsData.java index 3acd5fe98..023d6a392 100644 --- a/bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/RdsTestData.java +++ b/bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/TestRdsData.java @@ -18,10 +18,13 @@ import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.measure.quantity.ElectricCurrent; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.junit.jupiter.api.Test; @@ -38,6 +41,7 @@ import org.openhab.core.library.unit.ImperialUnits; import org.openhab.core.library.unit.SIUnits; import org.openhab.core.library.unit.Units; import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; /** * test suite @@ -46,11 +50,11 @@ import org.openhab.core.types.State; * */ @NonNullByDefault -public class RdsTestData { +public class TestRdsData { private String load(String fileName) { - try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName)); - BufferedReader reader = new BufferedReader(file)) { + try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName), + StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(file)) { StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { @@ -259,14 +263,14 @@ public class RdsTestData { State state; QuantityType celsius; - state = dataPoints.getPointByClass("'TOa").getState(); assertTrue(state instanceof QuantityType); celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); assertNotNull(celsius); assertEquals(18.55, celsius.floatValue(), 0.01); - assertEquals("0.0", dataPoints.getPointByClass("'HDevElLd").getState().toString()); + assertEquals(new QuantityType(0, Units.AMPERE), + dataPoints.getPointByClass("'HDevElLd").getState()); state = dataPoints.getPointByClass("'SpHPcf").getState(); assertTrue(state instanceof QuantityType); @@ -316,7 +320,7 @@ public class RdsTestData { assertNotNull(celsius); assertEquals(35.00, celsius.floatValue(), 0.01); - assertEquals("30.0", dataPoints.getPointByClass("'WarmUpGrdnt").getState().toString()); + assertEquals(new QuantityType<>(30, Units.ONE), dataPoints.getPointByClass("'WarmUpGrdnt").getState()); state = dataPoints.getPointByClass("'TRBltnMsvAdj").getState(); assertTrue(state instanceof QuantityType); @@ -324,30 +328,35 @@ public class RdsTestData { assertNotNull(kelvin); assertEquals(35.0, celsius.floatValue(), 0.01); - assertEquals("0.0", dataPoints.getPointByClass("'Q22Q24ElLd").getState().toString()); - assertEquals("713.0", dataPoints.getPointByClass("'RAQual").getState().toString()); - assertEquals("0.0", dataPoints.getPointByClass("'TmpCmfBtn").getState().toString()); - assertEquals("0.0", dataPoints.getPointByClass("'CmfBtn").getState().toString()); - assertEquals("0.0", dataPoints.getPointByClass("'RPscDet").getState().toString()); - assertEquals("1.0", dataPoints.getPointByClass("'EnHCtl").getState().toString()); - assertEquals("0.0", dataPoints.getPointByClass("'EnRPscDet").getState().toString()); - assertEquals("2.0", dataPoints.getPointByClass("'OffPrtCnf").getState().toString()); - assertEquals("3.0", dataPoints.getPointByClass("'OccMod").getState().toString()); - assertEquals("5.0", dataPoints.getPointByClass("'REei").getState().toString()); - assertEquals("2.0", dataPoints.getPointByClass("'DhwMod").getState().toString()); - assertEquals("2.0", dataPoints.getPointByClass("'HCSta").getState().toString()); - assertEquals("4.0", dataPoints.getPointByClass("'PrOpModRsn").getState().toString()); - assertEquals("6.0", dataPoints.getPointByClass("'HCtrSet").getState().toString()); - assertEquals("2.0", dataPoints.getPointByClass("'OsscSet").getState().toString()); - assertEquals("4.0", dataPoints.getPointByClass("'RAQualInd").getState().toString()); - assertEquals("500.0", dataPoints.getPointByClass("'KickCyc").getState().toString()); - assertEquals("180000.0", dataPoints.getPointByClass("'BoDhwTiOnMin").getState().toString()); - assertEquals("180000.0", dataPoints.getPointByClass("'BoDhwTiOffMin").getState().toString()); - assertEquals("UNDEF", dataPoints.getPointByClass("'ROpModSched").getState().toString()); - assertEquals("UNDEF", dataPoints.getPointByClass("'DhwSched").getState().toString()); - assertEquals("UNDEF", dataPoints.getPointByClass("'ROpModSched").getState().toString()); - assertEquals("UNDEF", dataPoints.getPointByClass("'DhwSched").getState().toString()); - assertEquals("253140.0", dataPoints.getPointByClass("'OphH").getState().toString()); + assertEquals(new QuantityType<>(0, Units.AMPERE), dataPoints.getPointByClass("'Q22Q24ElLd").getState()); + assertEquals(new QuantityType<>(713, Units.PARTS_PER_MILLION), + dataPoints.getPointByClass("'RAQual").getState()); + + assertEquals(new QuantityType<>(0, Units.ONE), dataPoints.getPointByClass("'TmpCmfBtn").getState()); + assertEquals(new QuantityType<>(0, Units.ONE), dataPoints.getPointByClass("'CmfBtn").getState()); + assertEquals(new QuantityType<>(0, Units.ONE), dataPoints.getPointByClass("'RPscDet").getState()); + assertEquals(new QuantityType<>(1, Units.ONE), dataPoints.getPointByClass("'EnHCtl").getState()); + assertEquals(new QuantityType<>(0, Units.ONE), dataPoints.getPointByClass("'EnRPscDet").getState()); + assertEquals(new QuantityType<>(2, Units.ONE), dataPoints.getPointByClass("'OffPrtCnf").getState()); + assertEquals(new QuantityType<>(3, Units.ONE), dataPoints.getPointByClass("'OccMod").getState()); + assertEquals(new QuantityType<>(5, Units.ONE), dataPoints.getPointByClass("'REei").getState()); + assertEquals(new QuantityType<>(2, Units.ONE), dataPoints.getPointByClass("'DhwMod").getState()); + assertEquals(new QuantityType<>(2, Units.ONE), dataPoints.getPointByClass("'HCSta").getState()); + assertEquals(new QuantityType<>(4, Units.ONE), dataPoints.getPointByClass("'PrOpModRsn").getState()); + assertEquals(new QuantityType<>(6, Units.ONE), dataPoints.getPointByClass("'HCtrSet").getState()); + assertEquals(new QuantityType<>(2, Units.ONE), dataPoints.getPointByClass("'OsscSet").getState()); + assertEquals(new QuantityType<>(4, Units.ONE), dataPoints.getPointByClass("'RAQualInd").getState()); + + assertEquals(new QuantityType<>(500, Units.HOUR), dataPoints.getPointByClass("'KickCyc").getState()); + assertEquals(new QuantityType<>(3, Units.MINUTE), dataPoints.getPointByClass("'BoDhwTiOnMin").getState()); + assertEquals(new QuantityType<>(3, Units.MINUTE), dataPoints.getPointByClass("'BoDhwTiOffMin").getState()); + + assertEquals(UnDefType.UNDEF, dataPoints.getPointByClass("'ROpModSched").getState()); + assertEquals(UnDefType.UNDEF, dataPoints.getPointByClass("'DhwSched").getState()); + assertEquals(UnDefType.UNDEF, dataPoints.getPointByClass("'ROpModSched").getState()); + assertEquals(UnDefType.UNDEF, dataPoints.getPointByClass("'DhwSched").getState()); + + assertEquals(new QuantityType<>(253140, Units.MINUTE), dataPoints.getPointByClass("'OphH").getState()); } catch (RdsCloudException e) { fail(e.getMessage()); } diff --git a/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json index 6df106ccf..7071f6758 100644 --- a/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json @@ -371,7 +371,7 @@ -50, 80 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Outside air temperature", "objectName": "R(1)'TOa", "memberName": "PresentValue", @@ -420,7 +420,7 @@ 0, 50 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Comfort heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHCmf", "memberName": "PresentValue", @@ -444,7 +444,7 @@ 0, 50 ], - "descr": "°F", + "descr": "°F", "descriptionName": "Pre-comfort heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHPcf", "memberName": "PresentValue", @@ -468,7 +468,7 @@ 0, 50 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Economy heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHEco", "memberName": "PresentValue", @@ -492,7 +492,7 @@ 0, 50 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Protection heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHPrt", "memberName": "PresentValue", @@ -517,7 +517,7 @@ 12, 35 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Room temperature setpoint", "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTR", "memberName": "PresentValue", @@ -590,7 +590,7 @@ 0, 50 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Room temperature", "objectName": "R(1)'RHvacCoo'RTemp", "memberName": "PresentValue", @@ -614,7 +614,7 @@ 0, 50 ], - "descr": "°C", + "descr": "°C", "descriptionName": "Max. heating setpoint", "objectName": "R(1)'SpTRMaxHCmf", "memberName": "PresentValue", diff --git a/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json index 89b4c92cb..f00ee65e5 100644 --- a/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json @@ -470,7 +470,7 @@ -50, 80 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Outside air temperature", "objectName": "R(1)'TOa", "memberName": "PresentValue", @@ -497,7 +497,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Comfort heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHCmf", "memberName": "PresentValue", @@ -523,7 +523,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Economy heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHPcf", "memberName": "PresentValue", @@ -549,7 +549,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Unoccupied heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHEco", "memberName": "PresentValue", @@ -575,7 +575,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Protection heating setpoint", "objectName": "R(1)'RHvacCoo'TCtlH'SpHPrt", "memberName": "PresentValue", @@ -602,7 +602,7 @@ 6, 35 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Room temperature setpoint", "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTR", "memberName": "PresentValue", @@ -681,7 +681,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Room temperature", "objectName": "R(1)'RHvacCoo'RTemp", "memberName": "PresentValue", @@ -707,7 +707,7 @@ 0, 50 ], - "descr": "�C", + "descr": "°C", "descriptionName": "Max. heating setpoint", "objectName": "R(1)'SpTRMaxHCmf", "memberName": "PresentValue",