[siemensrds] Binding no longer fails if thermostat does not use optional features (#13888)
* [siemensrds] fix charset; ansi => utf-8 * [siemensrds] refactor class so CI build runs tests w/o errors * [siemensrds] add missing UoM; fix compiler error * [siemensrds] fix issue #13887 Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
parent
b9f092fdb2
commit
8e31d8f0ca
@ -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<String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ElectricCurrent>(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());
|
||||
}
|
||||
@ -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",
|
||||
|
||||
@ -470,7 +470,7 @@
|
||||
-50,
|
||||
80
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Outside air temperature",
|
||||
"objectName": "R(1)'TOa",
|
||||
"memberName": "PresentValue",
|
||||
@ -497,7 +497,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Comfort heating setpoint",
|
||||
"objectName": "R(1)'RHvacCoo'TCtlH'SpHCmf",
|
||||
"memberName": "PresentValue",
|
||||
@ -523,7 +523,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Economy heating setpoint",
|
||||
"objectName": "R(1)'RHvacCoo'TCtlH'SpHPcf",
|
||||
"memberName": "PresentValue",
|
||||
@ -549,7 +549,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Unoccupied heating setpoint",
|
||||
"objectName": "R(1)'RHvacCoo'TCtlH'SpHEco",
|
||||
"memberName": "PresentValue",
|
||||
@ -575,7 +575,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Protection heating setpoint",
|
||||
"objectName": "R(1)'RHvacCoo'TCtlH'SpHPrt",
|
||||
"memberName": "PresentValue",
|
||||
@ -602,7 +602,7 @@
|
||||
6,
|
||||
35
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Room temperature setpoint",
|
||||
"objectName": "R(1)'RHvacCoo'SpTRDtr'SpTR",
|
||||
"memberName": "PresentValue",
|
||||
@ -681,7 +681,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Room temperature",
|
||||
"objectName": "R(1)'RHvacCoo'RTemp",
|
||||
"memberName": "PresentValue",
|
||||
@ -707,7 +707,7 @@
|
||||
0,
|
||||
50
|
||||
],
|
||||
"descr": "<EFBFBD>C",
|
||||
"descr": "°C",
|
||||
"descriptionName": "Max. heating setpoint",
|
||||
"objectName": "R(1)'SpTRMaxHCmf",
|
||||
"memberName": "PresentValue",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user