From e361d3477357cae3c6480c2c1a17c1413643be3a Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Sun, 24 May 2020 11:27:58 +0100 Subject: [PATCH 1/4] [siemensrds] null annotations; JUnit; U-o-M; enhancements; bug; refactoring; logging Signed-off-by: Andrew Fiddian-Green --- .../siemensrds/internal/RdsAccessToken.java | 46 +- .../internal/RdsBindingConstants.java | 69 +- .../internal/RdsCloudConfiguration.java | 9 +- .../internal/RdsCloudException.java | 5 +- .../siemensrds/internal/RdsCloudHandler.java | 79 +- .../siemensrds/internal/RdsConfiguration.java | 6 +- .../siemensrds/internal/RdsDataPoints.java | 607 +-- .../siemensrds/internal/RdsDebouncer.java | 19 +- .../internal/RdsDiscoveryService.java | 136 +- .../siemensrds/internal/RdsHandler.java | 278 +- .../internal/RdsHandlerFactory.java | 14 +- .../siemensrds/internal/RdsPlants.java | 43 +- .../binding/siemensrds/points/BasePoint.java | 194 + .../siemensrds/points/NestedNumberPoint.java | 84 + .../siemensrds/points/NestedNumberValue.java | 33 + .../siemensrds/points/NumberPoint.java | 53 + .../siemensrds/points/PointDeserializer.java | 119 + .../siemensrds/points/StringPoint.java | 55 + .../binding/siemensrds/points/UndefPoint.java | 42 + .../resources/ESH-INF/thing/thing-types.xml | 1 + .../binding/siemensrds/test/RdsTestData.java | 3416 +++++++++++++++++ 21 files changed, 4646 insertions(+), 662 deletions(-) create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/UndefPoint.java create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/RdsTestData.java diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java index 5507cee3baaa7..6107d90d60083 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java @@ -30,12 +30,12 @@ import javax.net.ssl.HttpsURLConnection; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; /** @@ -44,27 +44,30 @@ * @author Andrew Fiddian-Green - Initial contribution * */ -class RdsAccessToken { +@NonNullByDefault +public class RdsAccessToken { /* * NOTE: requires a static logger because the class has static methods */ - protected static final Logger LOGGER = LoggerFactory.getLogger(RdsAccessToken.class); + protected final Logger logger = LoggerFactory.getLogger(RdsAccessToken.class); private static final Gson GSON = new Gson(); + @Nullable @SerializedName("access_token") private String accessToken; + @Nullable @SerializedName(".expires") private String expires; + @Nullable private Date expDate = null; /* - * private method: execute the HTTP POST on the server + * public static method: execute the HTTP POST on the server */ - private static String httpGetTokenJson(String apiKey, String user, String password) - throws RdsCloudException, IOException { + public static String httpGetTokenJson(String apiKey, String payload) throws RdsCloudException, IOException { /* * NOTE: this class uses JAVAX HttpsURLConnection library instead of the * preferred JETTY library; the reason is that JETTY does not allow sending the @@ -85,12 +88,12 @@ private static String httpGetTokenJson(String apiKey, String user, String passwo try (OutputStream outputStream = https.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream)) { - dataOutputStream.writeBytes(String.format(TOKEN_REQUEST, user, password)); + dataOutputStream.writeBytes(payload); dataOutputStream.flush(); } if (https.getResponseCode() != HttpURLConnection.HTTP_OK) { - throw new RdsCloudException("invalid HTTP response"); + throw new IOException(https.getResponseMessage()); } try (InputStream inputStream = https.getInputStream(); @@ -106,35 +109,34 @@ private static String httpGetTokenJson(String apiKey, String user, String passwo } /* - * public method: execute a POST on the cloud server, parse the JSON, and create - * a class that encapsulates the data + * public method: parse the JSON, and create a class that encapsulates the data */ - public static @Nullable RdsAccessToken create(String apiKey, String user, String password) { - try { - String json = httpGetTokenJson(apiKey, user, password); - return GSON.fromJson(json, RdsAccessToken.class); - } catch (JsonSyntaxException | RdsCloudException | IOException e) { - LOGGER.warn("create {}: \"{}\"", e.getClass().getName(), e.getMessage()); - return null; - } + @Nullable + public static RdsAccessToken createFromJson(String json) { + return GSON.fromJson(json, RdsAccessToken.class); } /* * public method: return the access token */ - public String getToken() { - return accessToken; + public String getToken() throws RdsCloudException { + String accessToken = this.accessToken; + if (accessToken != null) { + return accessToken; + } + throw new RdsCloudException("no access token"); } /* * public method: check if the token has expired */ - public Boolean isExpired() { + public boolean isExpired() { + Date expDate = this.expDate; if (expDate == null) { try { expDate = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z").parse(expires); } catch (ParseException e) { - LOGGER.debug("isExpired: expiry date parsing exception"); + logger.debug("isExpired: expiry date parsing exception"); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsBindingConstants.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsBindingConstants.java index b0fa690a672db..67135fed79e34 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsBindingConstants.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsBindingConstants.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.siemensrds.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.thing.ThingTypeUID; /** @@ -19,6 +20,7 @@ * * @author Andrew Fiddian-Green - Initial contribution */ +@NonNullByDefault public class RdsBindingConstants { /* @@ -101,42 +103,46 @@ public class RdsBindingConstants { public static final String PROP_PLANT_ID = "plantId"; /* - * ==================== USED DATA POINTS ========================== where: HIE_ - * = the Hierarchy Name in the ClimatixIc server CHA_ = the Channel ID in the - * OpenHAB binding + * ==================== USED DATA POINTS ========================== + * + * where: HIE_xxx = the point class suffix part of the hierarchy name in the + * ClimatixIc server, and CHA_xxx = the Channel ID in the OpenHAB binding + * */ - // device name - protected static final String HIE_DESCRIPTION = "R(1)'Description"; + public static final String HIE_DESCRIPTION = "'Description"; + + // online state + public static final String HIE_ONLINE = "#Online"; // room (actual) temperature (read-only) protected static final String CHA_ROOM_TEMP = "roomTemperature"; - private static final String HIE_ROOM_TEMP = "RTemp"; + public static final String HIE_ROOM_TEMP = "'RTemp"; // room relative humidity (read-only) protected static final String CHA_ROOM_HUMIDITY = "roomHumidity"; - private static final String HIE_ROOM_HUMIDITY = "RHuRel"; + public static final String HIE_ROOM_HUMIDITY = "'RHuRel"; // room air quality (low/med/high) (read-only) protected static final String CHA_ROOM_AIR_QUALITY = "roomAirQuality"; - private static final String HIE_ROOM_AIR_QUALITY = "RAQualInd"; + public static final String HIE_ROOM_AIR_QUALITY = "'RAQualInd"; // energy savings level (green leaf) (poor..excellent) (read-write) // note: writing the value "5" forces the device to green leaf mode protected static final String CHA_ENERGY_SAVINGS_LEVEL = "energySavingsLevel"; - protected static final String HIE_ENERGY_SAVINGS_LEVEL = "REei"; + public static final String HIE_ENERGY_SAVINGS_LEVEL = "'REei"; // outside air temperature (read-only) protected static final String CHA_OUTSIDE_TEMP = "outsideTemperature"; - private static final String HIE_OUTSIDE_TEMP = "TOa"; + public static final String HIE_OUTSIDE_TEMP = "'TOa"; // set-point override (read-write) protected static final String CHA_TARGET_TEMP = "targetTemperature"; - private static final String HIE_TARGET_TEMP = "SpTR"; + public static final String HIE_TARGET_TEMP = "'SpTR"; // heating/cooling state (read-only) protected static final String CHA_OUTPUT_STATE = "thermostatOutputState"; - private static final String HIE_OUTPUT_STATE = "HCSta"; + public static final String HIE_OUTPUT_STATE = "'HCSta"; /* * thermostat occupancy state (absent, present) (read-write) NOTE: uses @@ -144,7 +150,7 @@ public class RdsBindingConstants { * absent, present states */ protected static final String CHA_STAT_OCC_MODE_PRESENT = "occupancyModePresent"; - protected static final String HIE_STAT_OCC_MODE_PRESENT = "OccMod"; + public static final String HIE_STAT_OCC_MODE_PRESENT = "'OccMod"; /* * thermostat program mode (read-write) NOTE: uses different parameters as @@ -153,8 +159,8 @@ public class RdsBindingConstants { * to command to the auto mode */ protected static final String CHA_STAT_AUTO_MODE = "thermostatAutoMode"; - private static final String HIE_PR_OP_MOD_RSN = "PrOpModRsn"; - protected static final String HIE_STAT_CMF_BTN = "CmfBtn"; + public static final String HIE_PR_OP_MOD_RSN = "'PrOpModRsn"; + public static final String HIE_STAT_CMF_BTN = "'CmfBtn"; /* * domestic hot water state (off, on) (read-write) NOTE: uses different @@ -162,7 +168,7 @@ public class RdsBindingConstants { * states */ protected static final String CHA_DHW_OUTPUT_STATE = "hotWaterOutputState"; - private static final String HIE_DHW_OUTPUT_STATE = "DhwMod"; + public static final String HIE_DHW_OUTPUT_STATE = "'DhwMod"; /* * domestic hot water program mode (manual, auto) (read-write) NOTE: uses @@ -215,17 +221,38 @@ public class RdsBindingConstants { * private static final String HIE_COMFORT_BUTTON = "CmfBtn"; * */ + + /* + * logger strings + */ + public static final String LOG_HTTP_COMMAND = "{} for url {} characters long"; + public static final String LOG_CONTENT_LENGTH = "{} {} characters.."; + public static final String LOG_PAYLOAD_FMT = "{} {}"; + + public static final String LOG_HTTP_COMMAND_ABR = "{} for url {} characters long (set log level to TRACE to see full url).."; + public static final String LOG_CONTENT_LENGTH_ABR = "{} {} characters (set log level to TRACE to see full string).."; + public static final String LOG_PAYLOAD_FMT_ABR = "{} {} ..."; + + public static final String LOG_RECEIVED_MSG = "received"; + public static final String LOG_RECEIVED_MARK = "<<"; + + public static final String LOG_SENDING_MSG = "sending"; + public static final String LOG_SENDING_MARK = ">>"; + + public static final String LOG_SYSTEM_EXCEPTION = "system exception in {}, type={}, message=\"{}\""; + public static final String LOG_RUNTIME_EXCEPTION = "runtime exception in {}, type={}, message=\"{}\""; } /** * @author Andrew Fiddian-Green - Initial contribution */ +@NonNullByDefault class ChannelMap { - public String channelId; - public String hierarchyName; + public String id; + public String clazz; - public ChannelMap(String channelId, String hierarchyName) { - this.channelId = channelId; - this.hierarchyName = hierarchyName; + public ChannelMap(String channelId, String pointClass) { + this.id = channelId; + this.clazz = pointClass; } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudConfiguration.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudConfiguration.java index 75b71b646caa2..c95347bee17cf 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudConfiguration.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudConfiguration.java @@ -12,16 +12,19 @@ */ package org.openhab.binding.siemensrds.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link RdsCloudConfiguration} class contains the thing configuration * parameters for the Climatix IC cloud user account * * @author Andrew Fiddian-Green - Initial contribution */ +@NonNullByDefault public class RdsCloudConfiguration { - public String userEmail; - public String userPassword; + public String userEmail = ""; + public String userPassword = ""; public int pollingInterval; - public String apiKey; + public String apiKey = ""; } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudException.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudException.java index d01b12a6dcdb4..ecaa5b98bcfc3 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudException.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudException.java @@ -12,13 +12,16 @@ */ package org.openhab.binding.siemensrds.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * Custom Cloud Server communication exception * * @author Andrew Fiddian-Green - Initial contribution * */ -public class RdsCloudException extends RuntimeException { +@NonNullByDefault +public class RdsCloudException extends Exception { private static final long serialVersionUID = -7048044632627280917L; diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java index 614a9b45c8a68..a084d4c490354 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java @@ -14,6 +14,10 @@ import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; +import java.io.IOException; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.ThingStatus; @@ -23,6 +27,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonParseException; + /** * The {@link RdsCloudHandler} is the handler for Siemens RDS cloud account ( * also known as the Climatix IC server account ) @@ -30,12 +36,16 @@ * @author Andrew Fiddian-Green - Initial contribution * */ +@NonNullByDefault public class RdsCloudHandler extends BaseBridgeHandler { private final Logger logger = LoggerFactory.getLogger(RdsCloudHandler.class); - private RdsCloudConfiguration config; - private RdsAccessToken accessToken; + @Nullable + private RdsCloudConfiguration config = null; + + @Nullable + private RdsAccessToken accessToken = null; public RdsCloudHandler(Bridge bridge) { super(bridge); @@ -48,12 +58,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { @Override public void initialize() { - config = getConfigAs(RdsCloudConfiguration.class); - - if (config == null) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing configuration"); - return; - } + RdsCloudConfiguration config = this.config = getConfigAs(RdsCloudConfiguration.class); if (config.userEmail.isEmpty()) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing email address"); @@ -84,8 +89,12 @@ public void dispose() { * public method: used by RDS smart thermostat handlers return the polling * interval (seconds) */ - public int getPollInterval() { - return (config != null ? config.pollingInterval : -1); + public int getPollInterval() throws RdsCloudException { + RdsCloudConfiguration config = this.config; + if (config != null) { + return config.pollingInterval; + } + throw new RdsCloudException("missing polling interval"); } /* @@ -93,8 +102,40 @@ public int getPollInterval() { * necessary */ private synchronized void refreshToken() { + RdsCloudConfiguration config = this.config; + RdsAccessToken accessToken = this.accessToken; + if (accessToken == null || accessToken.isExpired()) { - accessToken = RdsAccessToken.create(config.apiKey, config.userEmail, config.userPassword); + try { + if (config == null) { + throw new RdsCloudException("missing configuration"); + } + + String url = URL_TOKEN; + String payload = String.format(TOKEN_REQUEST, config.userEmail, config.userPassword); + + logger.debug(LOG_HTTP_COMMAND, HTTP_POST, url.length()); + logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, payload); + + String json = RdsAccessToken.httpGetTokenJson(config.apiKey, payload); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK, + json.substring(0, Math.min(json.length(), 30))); + } + + accessToken = this.accessToken = RdsAccessToken.createFromJson(json); + ; + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage()); + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage()); + } } if (accessToken != null) { @@ -113,12 +154,20 @@ private synchronized void refreshToken() { * public method: used by RDS smart thermostat handlers to fetch the current * token */ - public synchronized String getToken() { + public synchronized String getToken() throws RdsCloudException { refreshToken(); - return (accessToken != null ? accessToken.getToken() : ""); + RdsAccessToken accessToken = this.accessToken; + if (accessToken != null) { + return accessToken.getToken(); + } + throw new RdsCloudException("no access token"); } - public String getApiKey() { - return (config != null ? config.apiKey : ""); + public String getApiKey() throws RdsCloudException { + RdsCloudConfiguration config = this.config; + if (config != null) { + return config.apiKey; + } + throw new RdsCloudException("no api key"); } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsConfiguration.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsConfiguration.java index 581105b91caa9..8d0ddc42f4fde 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsConfiguration.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsConfiguration.java @@ -12,14 +12,16 @@ */ package org.openhab.binding.siemensrds.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; + /** * The {@link RdsConfiguration} class contains the thing configuration * parameters for RDS thermostats * * @author Andrew Fiddian-Green - Initial contribution */ - +@NonNullByDefault public class RdsConfiguration { - public String plantId; + public String plantId = ""; } 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 a021dca973c23..42cab1b2c1cdd 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 @@ -21,34 +21,29 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import javax.net.ssl.HttpsURLConnection; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.smarthome.core.library.types.DecimalType; -import org.eclipse.smarthome.core.library.types.OnOffType; -import org.eclipse.smarthome.core.library.types.StringType; -import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.siemensrds.points.BasePoint; +import org.openhab.binding.siemensrds.points.PointDeserializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.JsonParseException; -import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; /** @@ -58,20 +53,31 @@ * @author Andrew Fiddian-Green - Initial contribution * */ -class RdsDataPoints { +@NonNullByDefault +public class RdsDataPoints { /* * NOTE: requires a static logger because the class has static methods */ - protected static final Logger LOGGER = LoggerFactory.getLogger(RdsDataPoints.class); + protected final Logger logger = LoggerFactory.getLogger(RdsDataPoints.class); private static final Gson GSON = new GsonBuilder().registerTypeAdapter(BasePoint.class, new PointDeserializer()) .create(); + @Nullable @SerializedName("totalCount") private String totalCount; + @Nullable @SerializedName("values") - private Map points; + public Map points; + + /* + * this is a second index into to the points Map above; the purpose is to allow + * point lookups by a) pointId (which we do directly from the Map, and b) by + * pointClass (which we do indirectly "double dereferenced" via this second + * index + */ + private Map indexClassToId = new HashMap<>(); private String valueFilter = ""; @@ -97,10 +103,8 @@ protected static String httpGenericGetJson(String apiKey, String token, String u https.setRequestProperty(SUBSCRIPTION_KEY, apiKey); https.setRequestProperty(AUTHORIZATION, String.format(BEARER, token)); - int responseCode = https.getResponseCode(); - - if (responseCode != HttpURLConnection.HTTP_OK) { - throw new RdsCloudException("invalid HTTP response"); + if (https.getResponseCode() != HttpURLConnection.HTTP_OK) { + throw new IOException(https.getResponseMessage()); } try (InputStream inputStream = https.getInputStream(); @@ -116,30 +120,18 @@ protected static String httpGenericGetJson(String apiKey, String token, String u } /* - * public static method: execute a GET on the cloud server, parse the JSON, and - * create a real instance of this class that encapsulates all the retrieved data - * point values + * public static method: parse the JSON, and create a real instance of this + * class that encapsulates the data data point values */ - public static @Nullable RdsDataPoints create(String apiKey, String token, String plantId) { - try { - String json = httpGenericGetJson(apiKey, token, String.format(URL_POINTS, plantId)); - - LOGGER.debug("create: received {} characters (log:set TRACE to see all)", json.length()); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("create: response={}", json); - } - - return GSON.fromJson(json, RdsDataPoints.class); - } catch (JsonSyntaxException | RdsCloudException | IOException e) { - LOGGER.warn("create {}: \"{}\"", e.getClass().getName(), e.getMessage()); - return null; - } + @Nullable + public static RdsDataPoints createFromJson(String json) { + return GSON.fromJson(json, RdsDataPoints.class); } /* * private method: execute an HTTP PUT on the server to set a data point value */ - private void httpSetPointValueJson(String apiKey, String token, String pointId, String json) + private void httpSetPointValueJson(String apiKey, String token, String pointUrl, String json) throws RdsCloudException, UnsupportedEncodingException, ProtocolException, MalformedURLException, IOException { /* @@ -147,7 +139,7 @@ private void httpSetPointValueJson(String apiKey, String token, String pointId, * preferred JETTY library; the reason is that JETTY does not allow sending the * square brackets characters "[]" verbatim over HTTP connections */ - URL url = new URL(String.format(URL_SETVAL, pointId)); + URL url = new URL(pointUrl); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); @@ -166,150 +158,99 @@ private void httpSetPointValueJson(String apiKey, String token, String pointId, } if (https.getResponseCode() != HttpURLConnection.HTTP_OK) { - throw new RdsCloudException("invalid HTTP response"); + throw new IOException(https.getResponseMessage()); } } /* - * private method: retrieve the data point with the given hierarchyName + * public method: retrieve the data point with the given pointClass */ - private BasePoint getPoint(String hierarchyName) { - if (hierarchyName != null) { - for (Map.Entry entry : points.entrySet()) { - BasePoint point = entry.getValue(); - if (point != null && point.hierarchyName != null && point.hierarchyName.contains(hierarchyName)) { - return point; - } - } + public BasePoint getPointByClass(String pointClass) throws RdsCloudException { + if (indexClassToId.isEmpty()) { + initClassToIdNameIndex(); } - return null; - } - - /* - * private method: retrieve the data point with the given hierarchyName - */ - private String getPointId(String hierarchyName) { - if (hierarchyName != null) { - for (Map.Entry entry : points.entrySet()) { - BasePoint point = entry.getValue(); - if (point != null && point.hierarchyName != null && point.hierarchyName.contains(hierarchyName)) { - return entry.getKey(); - } + @Nullable + String pointId = indexClassToId.get(pointClass); + if (pointId instanceof String) { + BasePoint point = getPointById(pointId); + if (point instanceof BasePoint) { + return point; } } - return null; + throw new RdsCloudException(String.format("pointClass \"%s\" not found", pointClass)); } /* - * public method: retrieve the state of the data point with the given - * hierarchyName + * public method: retrieve the data point with the given pointId */ - public synchronized State getRaw(String hierarchyName) { - BasePoint point = getPoint(hierarchyName); - if (point != null) { - State state = point.getRaw(); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("getRaw: {}={}", hierarchyName, state.toString()); - } - return state; - } - LOGGER.warn("getRaw: {}=No Value!", hierarchyName); - return null; - } - - /* - * public method: return the presentPriority of the data point with the given - * hierarchyName - */ - public synchronized int getPresPrio(String hierarchyName) { - BasePoint point = getPoint(hierarchyName); - if (point != null) { - int presentPriority = point.getPresentPriority(); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("getPresentPriority: {}={}", hierarchyName, presentPriority); + public BasePoint getPointById(String pointId) throws RdsCloudException { + Map points = this.points; + if (points != null) { + @Nullable + BasePoint point = points.get(pointId); + if (point instanceof BasePoint) { + return point; } - return presentPriority; } - LOGGER.warn("getPresentPriority: {}=No Value!", hierarchyName); - return 0; + throw new RdsCloudException(String.format("pointId \"%s\" not found", pointId)); } /* - * public method: return the presentPriority of the data point with the given - * hierarchyName + * private method: retrieve Id of data point with the given pointClass */ - public synchronized int asInt(String hierarchyName) { - BasePoint point = getPoint(hierarchyName); - if (point != null) { - int value = point.asInt(); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("asInt: {}={}", hierarchyName, value); - } - return value; + public String pointClassToId(String pointClass) throws RdsCloudException { + if (indexClassToId.isEmpty()) { + initClassToIdNameIndex(); } - LOGGER.warn("getAsInt: {}=No Value!", hierarchyName); - return 0; - } - - /* - * public method: retrieve the enum state of the data point with the given - * hierarchyName - */ - public synchronized State getEnum(String hierarchyName) { - BasePoint point = getPoint(hierarchyName); - if (point != null) { - State state = point.getEnum(); - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("getEnum: {}={}", hierarchyName, state.toString()); - } - return state; + @Nullable + String pointId = indexClassToId.get(pointClass); + if (pointId instanceof String) { + return pointId; } - LOGGER.warn("getEnum: {}=No Value!", hierarchyName); - return null; + throw new RdsCloudException(String.format("no pointId to match pointClass \"%s\"", pointClass)); } /* * public method: return the state of the "Online" data point */ - public Boolean isOnline() { - for (Map.Entry entry : points.entrySet()) { - BasePoint point = entry.getValue(); - if (point != null && point.memberName != null && point.memberName.equals("Online")) { - return (point.asInt() == 1); - } - } - return false; + public boolean isOnline() throws RdsCloudException { + BasePoint point = getPointByClass(HIE_ONLINE); + return "Online".equals(point.getEnum().toString()); } /* * public method: set a new data point value on the server */ - public void setValue(String apiKey, String token, String hierarchyName, String value) { - String pointId = getPointId(hierarchyName); - BasePoint point = getPoint(hierarchyName); - - if (pointId != null && point != null) { - String json = point.commandJson(value); - - LOGGER.debug("setValue: {}=>{}", hierarchyName, json); - - try { - httpSetPointValueJson(apiKey, token, pointId, json); - } catch (RdsCloudException | IOException e) { - LOGGER.warn("setValue {} {}: \"{}\"", hierarchyName, e.getClass().getName(), e.getMessage()); - return; + public void setValue(String apiKey, String token, String pointClass, String value) { + try { + String pointId = pointClassToId(pointClass); + BasePoint point = getPointByClass(pointClass); + + String url = String.format(URL_SETVAL, pointId); + String payload = point.commandJson(value); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_HTTP_COMMAND, HTTP_PUT, url.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + logger.trace(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, payload); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_HTTP_COMMAND_ABR, HTTP_PUT, url.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_SENDING_MARK, url.substring(0, Math.min(url.length(), 30))); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_SENDING_MARK, + payload.substring(0, Math.min(payload.length(), 30))); } - } else { - LOGGER.warn("setValue: point or pointId not found for {}", hierarchyName); + + httpSetPointValueJson(apiKey, token, url, payload); + ; + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "setValue()", e.getClass().getName(), e.getMessage()); + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "setValue()", e.getClass().getName(), e.getMessage()); } } /* - * public method: set a new data point value on the server + * public method: refresh the data point value from the server */ public boolean refresh(String apiKey, String token) { try { @@ -319,337 +260,129 @@ public boolean refresh(String apiKey, String token) { String pointId; for (ChannelMap chan : CHAN_MAP) { - pointId = getPointId(chan.hierarchyName); - if (pointId != null) { + pointId = pointClassToId(chan.clazz); + if (!pointId.isEmpty()) { set.add(String.format("\"%s\"", pointId)); } } - for (Map.Entry entry : points.entrySet()) { - BasePoint point = entry.getValue(); - if (point != null && point.memberName != null && point.memberName.equals("Online")) { - set.add(String.format("\"%s\"", entry.getKey())); - break; + Map points = this.points; + if (points != null) { + for (Map.Entry entry : points.entrySet()) { + @Nullable + Object object = entry.getValue(); + if (object instanceof BasePoint) { + BasePoint point = (BasePoint) object; + if ("Online".equals(point.getMemberName())) { + set.add(String.format("\"%s\"", entry.getKey())); + break; + } + } } } valueFilter = String.join(",", set); } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("refresh: request={}", valueFilter); - } + String url = String.format(URL_VALUES, valueFilter); - String json = httpGenericGetJson(apiKey, token, String.format(URL_VALUES, valueFilter)); + if (logger.isTraceEnabled()) { + logger.trace(LOG_HTTP_COMMAND, HTTP_GET, url.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_HTTP_COMMAND_ABR, HTTP_GET, url.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_SENDING_MARK, url.substring(0, Math.min(url.length(), 30))); + } - LOGGER.debug("refresh: received {} characters (log:set TRACE to see all)", json.length()); + String json = httpGenericGetJson(apiKey, token, url); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("refresh: response={}", json); + if (logger.isTraceEnabled()) { + logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK, json.substring(0, Math.min(json.length(), 30))); } @Nullable - RdsDataPoints newPoints = GSON.fromJson(json, RdsDataPoints.class); + Object newPoints = GSON.fromJson(json, RdsDataPoints.class); - synchronized (this) { - for (Map.Entry entry : newPoints.points.entrySet()) { - BasePoint newPoint = entry.getValue(); - BasePoint existingPoint = points.get(entry.getKey()); - - if (newPoint instanceof BooleanPoint && existingPoint instanceof BooleanPoint) { - ((BooleanPoint) existingPoint).value = ((BooleanPoint) newPoint).value; - } else - - if (newPoint instanceof TextPoint && existingPoint instanceof TextPoint) { - ((TextPoint) existingPoint).value = ((TextPoint) newPoint).value; - } else - - if (newPoint instanceof NumericPoint && existingPoint instanceof NumericPoint) { - ((NumericPoint) existingPoint).value = ((NumericPoint) newPoint).value; - } else - - if (newPoint instanceof InnerValuePoint && existingPoint instanceof InnerValuePoint) { - ((InnerValuePoint) existingPoint).inner.value = ((InnerValuePoint) newPoint).inner.value; - ((InnerValuePoint) existingPoint).inner.presentPriority = ((InnerValuePoint) newPoint).inner.presentPriority; - } else { - LOGGER.warn("refresh: point type mismatch"); - } - - } + if (!(newPoints instanceof RdsDataPoints)) { + throw new RdsCloudException("new points list invalid"); } - return true; - } catch (JsonSyntaxException | RdsCloudException | IOException e) { - LOGGER.warn("refresh {}: \"{}\"", e.getClass().getName(), e.getMessage()); - return false; - } - } -} - -/** - * private class: a generic data point - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -abstract class BasePoint { - @SerializedName("rep") - protected int rep; - @SerializedName("type") - protected int type; - @SerializedName("write") - protected boolean write; - @SerializedName("descr") - protected String descr; - @SerializedName("limits") - protected float[] limits; - @SerializedName("descriptionName") - protected String descriptionName; - @SerializedName("objectName") - protected String objectName; - @SerializedName("memberName") - protected String memberName; - @SerializedName("hierarchyName") - protected String hierarchyName; - @SerializedName("translated") - protected boolean translated; - - private String[] enumVals; - private boolean enumParsed = false; - protected boolean isEnum = false; + Map newPointsMap = ((RdsDataPoints) newPoints).points; - /* - * initialize the enum value list - */ - private boolean initEnum() { - if (!enumParsed) { - if (descr != null && descr.contains("*")) { - enumVals = descr.split("\\*"); - isEnum = true; + if (newPointsMap == null) { + throw new RdsCloudException("new points map empty"); } - } - enumParsed = true; - return isEnum; - } - public int getPresentPriority() { - return 0; - } + synchronized (this) { + for (Map.Entry entry : newPointsMap.entrySet()) { + @Nullable + String pointId = entry.getKey(); + if (!(pointId instanceof String)) { + throw new RdsCloudException("invalid new point id"); + } - /* - * => MUST be overridden - */ - protected abstract int asInt(); + @Nullable + Object newPoint = entry.getValue(); + if (!(newPoint instanceof BasePoint)) { + throw new RdsCloudException("invalid new point"); + } - protected boolean isEnum() { - return (enumParsed ? isEnum : initEnum()); - } + @Nullable + BasePoint myPoint = getPointById(pointId); + if (!(myPoint instanceof BasePoint)) { + throw new RdsCloudException("existing point not found"); + } - public State getEnum() { - if (isEnum()) { - int index = asInt(); - if (index >= 0 && index < enumVals.length) { - return new StringType(enumVals[index]); - } - } - return null; - } + if (!(newPoint.getClass().equals(myPoint.getClass()))) { + throw new RdsCloudException("existing vs. new point class mismatch"); + } - /* - * property getter for openHAB => MUST be overridden - */ - public State getRaw() { - return null; - } + myPoint.refreshValueFrom((BasePoint) newPoint); - /* - * property getter for openHAB returns the "Units" of the point value - */ - public String getUnits() { - return (descr != null ? descr : ""); - } - - /* - * property getter for JSON => MAY be overridden - */ - public String commandJson(String newVal) { - if (isEnum()) { - for (int index = 0; index < enumVals.length; index++) { - if (enumVals[index].equals(newVal)) { - return String.format("{\"value\":%d}", index); + if (logger.isDebugEnabled()) { + logger.debug("refresh {}.{}: {} << {}", getDescription(), myPoint.getPointClass(), + myPoint.getState(), ((BasePoint) newPoint).getState()); + } } } - } - return String.format("{\"value\":%s}", newVal); - } -} - -/** - * private class a data point where "value" is a JSON text element - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class TextPoint extends BasePoint { - @SerializedName("value") - protected String value; - @Override - protected int asInt() { - try { - return Integer.parseInt(value); - } catch (Exception e) { - return -1; + return true; + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "refresh()", e.getClass().getName(), e.getMessage()); + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "refresh()", e.getClass().getName(), e.getMessage()); } + return false; } /* - * if appropriate return the enum string representation, otherwise return the - * decimal representation - */ - @Override - public State getRaw() { - return new StringType(value); - } -} - -/** - * private class a data point where "value" is a JSON boolean element - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class BooleanPoint extends BasePoint { - @SerializedName("value") - protected boolean value; - - @Override - protected int asInt() { - return (value ? 1 : 0); - } - - @Override - public State getRaw() { - return OnOffType.from(value); - } -} - -/** - * private class inner (helper) class for an embedded JSON numeric element - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class NestedValue { - @SerializedName("value") - protected float value; - @SerializedName("presentPriority") - protected float presentPriority; -} - -/** - * private class a data point where "value" is a nested JSON numeric element - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class InnerValuePoint extends BasePoint { - @SerializedName("value") - protected NestedValue inner; - - @Override - protected int asInt() { - return (inner != null ? (int) inner.value : -1); - } - - /* - * if appropriate return the enum string representation, otherwise return the - * decimal representation + * initialize the second index into to the points Map */ - @Override - public State getRaw() { - if (inner != null) { - return new DecimalType(inner.value); - } - return null; - } - - @Override - public int getPresentPriority() { - if (inner != null) { - return (int) inner.presentPriority; + @SuppressWarnings("null") + private void initClassToIdNameIndex() { + Map points = this.points; + if (points != null) { + indexClassToId = new HashMap<>(); + for (Entry entry : points.entrySet()) { + @Nullable + String pointKey = entry.getKey(); + @Nullable + BasePoint pointValue = entry.getValue(); + if (pointKey != null && pointValue != null) { + indexClassToId.put(pointValue.getPointClass(), pointKey); + } + } } - return 0; - } -} - -/** - * private class a data point where "value" is a JSON numeric element - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class NumericPoint extends BasePoint { - @SerializedName("value") - protected float value; - - @Override - protected int asInt() { - return (int) value; } /* - * if appropriate return the enum string representation, otherwise return the - * decimal representation + * public method: return the state of the "Description" data point */ - @Override - public State getRaw() { - return new DecimalType(value); - } -} - -/** - * private class a JSON de-serializer for the Data Point classes above - * - * @author Andrew Fiddian-Green - Initial contribution - * - */ -class PointDeserializer implements JsonDeserializer { - - @Override - public BasePoint deserialize(JsonElement element, Type guff, JsonDeserializationContext ctxt) - throws JsonParseException { - JsonObject obj = element.getAsJsonObject(); - JsonElement val = obj.get("value"); - - if (val != null) { - if (val.isJsonPrimitive()) { - if (val.getAsJsonPrimitive().isBoolean()) { - return ctxt.deserialize(obj, BooleanPoint.class); - } - if (val.getAsJsonPrimitive().isNumber()) { - return ctxt.deserialize(obj, NumericPoint.class); - } - if (val.getAsJsonPrimitive().isString()) { - return ctxt.deserialize(obj, TextPoint.class); - } - } else { - if (val.isJsonObject()) { - JsonElement rep = obj.get("rep"); - if (rep == null) { - return ctxt.deserialize(obj, InnerValuePoint.class); - } else { - if (rep.isJsonPrimitive() && rep.getAsJsonPrimitive().isNumber()) { - switch (rep.getAsInt()) { - case 1: - case 3: - return ctxt.deserialize(obj, InnerValuePoint.class); - } - } - } - } - } - } - return null; + public String getDescription() throws RdsCloudException { + return getPointByClass(HIE_DESCRIPTION).getState().toString(); } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java index bcfa6195e2173..94fa4c2a7b11b 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java @@ -18,27 +18,33 @@ import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + /** * The {@link RdsDebouncer} determines if change events should be forwarded to a * channel * * @author Andrew Fiddian-Green - Initial contribution */ +@NonNullByDefault public class RdsDebouncer { private final Map channels = new HashMap<>(); + @SuppressWarnings("null") + @NonNullByDefault static class DebounceDelay { private long expireTime; - public DebounceDelay(Boolean enabled) { + public DebounceDelay(boolean enabled) { if (enabled) { expireTime = new Date().getTime() + (DEBOUNCE_DELAY * 1000); } } - public Boolean timeExpired() { + public boolean timeExpired() { return (expireTime < new Date().getTime()); } } @@ -51,6 +57,13 @@ public void initialize(String channelId) { } public Boolean timeExpired(String channelId) { - return (channels.containsKey(channelId) ? channels.get(channelId).timeExpired() : true); + if (channels.containsKey(channelId)) { + @Nullable + Object debounceDelay = channels.get(channelId); + if (debounceDelay instanceof DebounceDelay) { + return ((DebounceDelay) debounceDelay).timeExpired(); + } + } + return true; } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java index bb074bd25a987..23612a390faf4 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java @@ -14,13 +14,17 @@ import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; +import java.io.IOException; import java.util.Collections; +import java.util.List; import java.util.Set; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResult; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; @@ -28,20 +32,27 @@ import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.ThingUID; import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.siemensrds.internal.RdsPlants.PlantInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonParseException; + /** * Discovery service for Siemens RDS thermostats * * @author Andrew Fiddian-Green - Initial contribution * */ +@NonNullByDefault public class RdsDiscoveryService extends AbstractDiscoveryService { private final Logger logger = LoggerFactory.getLogger(RdsDiscoveryService.class); + @Nullable private ScheduledFuture discoveryScheduler; + + @Nullable private RdsCloudHandler cloud; public static final Set DISCOVERABLE_THING_TYPES_UIDS = Collections @@ -64,10 +75,17 @@ public void deactivate() { @Override protected void startScan() { - if (cloud.getThing().getStatus() != ThingStatus.ONLINE) { - cloud.getToken(); + RdsCloudHandler cloud = this.cloud; + + if (cloud != null && cloud.getThing().getStatus() != ThingStatus.ONLINE) { + try { + cloud.getToken(); + } catch (RdsCloudException e) { + logger.debug("unexpected: {} = \"{}\"", e.getClass().getName(), e.getMessage()); + } } - if (cloud.getThing().getStatus() == ThingStatus.ONLINE) { + + if (cloud != null && cloud.getThing().getStatus() == ThingStatus.ONLINE) { discoverPlants(); } } @@ -76,8 +94,9 @@ protected void startScan() { protected void startBackgroundDiscovery() { logger.debug("start background discovery.."); + ScheduledFuture discoveryScheduler = this.discoveryScheduler; if (discoveryScheduler == null || discoveryScheduler.isCancelled()) { - discoveryScheduler = scheduler.scheduleWithFixedDelay(this::startScan, 10, DISCOVERY_REFRESH_PERIOD, + this.discoveryScheduler = scheduler.scheduleWithFixedDelay(this::startScan, 10, DISCOVERY_REFRESH_PERIOD, TimeUnit.SECONDS); } } @@ -86,53 +105,110 @@ protected void startBackgroundDiscovery() { protected void stopBackgroundDiscovery() { logger.debug("stop background discovery.."); + ScheduledFuture discoveryScheduler = this.discoveryScheduler; if (discoveryScheduler != null && !discoveryScheduler.isCancelled()) { discoveryScheduler.cancel(true); + this.discoveryScheduler = null; } } private void discoverPlants() { + RdsCloudHandler cloud = this.cloud; + if (cloud != null) { - RdsPlants plants = RdsPlants.create(cloud.getApiKey(), cloud.getToken()); - if (plants != null) { - for (RdsPlants.PlantInfo plant : plants.getPlants()) { - publishPlant(plant); + @Nullable + RdsPlants plantClass = null; + + try { + String url = URL_PLANTS; + + logger.debug(LOG_HTTP_COMMAND, HTTP_GET, url.length()); + logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + + String json = RdsDataPoints.httpGenericGetJson(cloud.getApiKey(), cloud.getToken(), url); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK, + json.substring(0, Math.min(json.length(), 30))); + } + + plantClass = RdsPlants.createFromJson(json); + ; + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "discoverPlants()", e.getClass().getName(), e.getMessage()); + return; + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "discoverPlants()", e.getClass().getName(), e.getMessage()); + return; + } + + if (plantClass != null) { + List plants = plantClass.getPlants(); + if (plants != null) { + for (PlantInfo plant : plants) { + publishPlant(plant); + } } } } } - private void publishPlant(RdsPlants.PlantInfo plant) { - if (plant != null) { + private void publishPlant(PlantInfo plant) { + RdsCloudHandler cloud = this.cloud; + try { + if (cloud == null) { + throw new RdsCloudException("missing cloud handler"); + } + String plantId = plant.getId(); + String url = String.format(URL_POINTS, plantId); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_HTTP_COMMAND, HTTP_GET, url.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_HTTP_COMMAND_ABR, HTTP_GET, url.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_SENDING_MARK, url.substring(0, Math.min(url.length(), 30))); + } - if (plantId != null && !plantId.isEmpty()) { - RdsDataPoints points = RdsDataPoints.create(cloud.getApiKey(), cloud.getToken(), plantId); + String json = RdsDataPoints.httpGenericGetJson(cloud.getApiKey(), cloud.getToken(), url); - if (points != null) { - State desc = points.getRaw(HIE_DESCRIPTION); + if (logger.isTraceEnabled()) { + logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK, json.substring(0, Math.min(json.length(), 30))); + } - if (desc != null) { - String label = desc.toString().replaceAll("\\s+", "_"); + RdsDataPoints points = RdsDataPoints.createFromJson(json); + if (points == null) { + throw new RdsCloudException("no points returned"); + } - ThingTypeUID typeUID = THING_TYPE_RDS; - ThingUID bridgeUID = cloud.getThing().getUID(); - ThingUID plantUID = new ThingUID(typeUID, bridgeUID, plantId); + State desc = points.getPointByClass(HIE_DESCRIPTION).getState(); + String label = desc.toString().replaceAll("\\s+", "_"); - DiscoveryResult disco = DiscoveryResultBuilder.create(plantUID).withBridge(bridgeUID) - .withLabel(label).withProperty(PROP_PLANT_ID, plantId) - .withRepresentationProperty(PROP_PLANT_ID).build(); + ThingTypeUID typeUID = THING_TYPE_RDS; + ThingUID bridgeUID = cloud.getThing().getUID(); + ThingUID plantUID = new ThingUID(typeUID, bridgeUID, plantId); - logger.debug("discovered typeUID={}, plantUID={}, brigeUID={}, label={}, plantId={}, ", typeUID, - plantUID, bridgeUID, label, plantId); + DiscoveryResult disco = DiscoveryResultBuilder.create(plantUID).withBridge(bridgeUID).withLabel(label) + .withProperty(PROP_PLANT_ID, plantId).withRepresentationProperty(PROP_PLANT_ID).build(); - thingDiscovered(disco); + logger.debug("discovered typeUID={}, plantUID={}, brigeUID={}, label={}, plantId={}, ", typeUID, plantUID, + bridgeUID, label, plantId); - return; - } - } - } + thingDiscovered(disco); + ; + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "publishPlant()", e.getClass().getName(), e.getMessage()); + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "publishPlant()", e.getClass().getName(), e.getMessage()); } - logger.debug("discovery error!"); } } 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 e9ba2fa22d90d..6a2216c17be4d 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 @@ -14,12 +14,17 @@ import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; +import java.io.IOException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import javax.measure.Unit; + +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.core.library.types.OnOffType; +import org.eclipse.smarthome.core.library.types.QuantityType; import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.ChannelUID; @@ -32,9 +37,12 @@ import org.eclipse.smarthome.core.types.Command; import org.eclipse.smarthome.core.types.RefreshType; import org.eclipse.smarthome.core.types.State; +import org.openhab.binding.siemensrds.points.BasePoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.gson.JsonParseException; + /** * The {@link RdsHandler} is the OpenHab Handler for Siemens RDS smart * thermostats @@ -42,19 +50,25 @@ * @author Andrew Fiddian-Green - Initial contribution * */ +@NonNullByDefault public class RdsHandler extends BaseThingHandler { protected final Logger logger = LoggerFactory.getLogger(RdsHandler.class); - private ScheduledFuture lazyPollingScheduler; - private ScheduledFuture fastPollingScheduler; + @Nullable + private ScheduledFuture lazyPollingScheduler = null; + + @Nullable + private ScheduledFuture fastPollingScheduler = null; private final AtomicInteger fastPollingCallsToGo = new AtomicInteger(); private RdsDebouncer debouncer = new RdsDebouncer(); + @Nullable private RdsConfiguration config = null; + @Nullable private RdsDataPoints points = null; public RdsHandler(Thing thing) { @@ -73,50 +87,54 @@ public void handleCommand(ChannelUID channelUID, Command command) { public void initialize() { updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.CONFIGURATION_PENDING); - config = getConfigAs(RdsConfiguration.class); + RdsConfiguration config = this.config = getConfigAs(RdsConfiguration.class); - if (config == null || config.plantId == null || config.plantId.isEmpty()) { + if (config.plantId.isEmpty()) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing Plant Id"); return; } - RdsCloudHandler cloud = getCloudHandler(); + updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.CONFIGURATION_PENDING); - if (cloud == null) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing cloud server handler"); - return; - } + try { + RdsCloudHandler cloud = getCloudHandler(); - if (cloud.getThing().getStatus() != ThingStatus.ONLINE) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "cloud server offline"); + if (cloud.getThing().getStatus() != ThingStatus.ONLINE) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "cloud server offline"); + return; + } + + initializePolling(); + } catch (RdsCloudException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing cloud server handler"); return; } - - initializePolling(); } public void initializePolling() { - RdsCloudHandler cloud = getCloudHandler(); - - if (cloud != null) { - int pollInterval = cloud.getPollInterval(); - - if (pollInterval > 0) { - // create a "lazy" polling scheduler - if (lazyPollingScheduler == null || lazyPollingScheduler.isCancelled()) { - lazyPollingScheduler = scheduler.scheduleWithFixedDelay(this::lazyPollingSchedulerExecute, - pollInterval, pollInterval, TimeUnit.SECONDS); - } - - // create a "fast" polling scheduler - fastPollingCallsToGo.set(FAST_POLL_CYCLES); - if (fastPollingScheduler == null || fastPollingScheduler.isCancelled()) { - fastPollingScheduler = scheduler.scheduleWithFixedDelay(this::fastPollingSchedulerExecute, - FAST_POLL_INTERVAL, FAST_POLL_INTERVAL, TimeUnit.SECONDS); - } + try { + int pollInterval = getCloudHandler().getPollInterval(); + + // create a "lazy" polling scheduler + ScheduledFuture lazyPollingScheduler = this.lazyPollingScheduler; + if (lazyPollingScheduler == null || lazyPollingScheduler.isCancelled()) { + this.lazyPollingScheduler = scheduler.scheduleWithFixedDelay(this::lazyPollingSchedulerExecute, + pollInterval, pollInterval, TimeUnit.SECONDS); + } - startFastPollingBurst(); + // create a "fast" polling scheduler + fastPollingCallsToGo.set(FAST_POLL_CYCLES); + ScheduledFuture fastPollingScheduler = this.fastPollingScheduler; + if (fastPollingScheduler == null || fastPollingScheduler.isCancelled()) { + this.fastPollingScheduler = scheduler.scheduleWithFixedDelay(this::fastPollingSchedulerExecute, + FAST_POLL_INTERVAL, FAST_POLL_INTERVAL, TimeUnit.SECONDS); } + + startFastPollingBurst(); + ; + } catch (RdsCloudException e) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage()); + logger.warn(LOG_SYSTEM_EXCEPTION, "initializePolling()", e.getClass().getName(), e.getMessage()); } } @@ -132,15 +150,17 @@ public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) { @Override public void dispose() { // clean up the lazy polling scheduler + ScheduledFuture lazyPollingScheduler = this.lazyPollingScheduler; if (lazyPollingScheduler != null && !lazyPollingScheduler.isCancelled()) { lazyPollingScheduler.cancel(true); - lazyPollingScheduler = null; + this.lazyPollingScheduler = null; } // clean up the fast polling scheduler + ScheduledFuture fastPollingScheduler = this.fastPollingScheduler; if (fastPollingScheduler != null && !fastPollingScheduler.isCancelled()) { fastPollingScheduler.cancel(true); - fastPollingScheduler = null; + this.fastPollingScheduler = null; } } @@ -178,96 +198,92 @@ private void fastPollingSchedulerExecute() { * states */ private void doPollNow() { - RdsCloudHandler cloud = getCloudHandler(); - - if (cloud == null) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing cloud server handler"); - return; - } - - String token = cloud.getToken(); + try { + RdsCloudHandler cloud = getCloudHandler(); - if (cloud.getThing().getStatus() != ThingStatus.ONLINE) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "cloud server offline"); - return; - } + if (cloud.getThing().getStatus() != ThingStatus.ONLINE) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "cloud server offline"); + return; + } - String apiKey = cloud.getApiKey(); + RdsDataPoints points = this.points; + if ((points == null || (!points.refresh(cloud.getApiKey(), cloud.getToken())))) { + points = fetchPoints(); + } - if (points == null || (!points.refresh(apiKey, token))) { - points = RdsDataPoints.create(apiKey, token, config.plantId); - } + if (points == null) { + if (getThing().getStatus() == ThingStatus.ONLINE) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing data points"); + } + throw new RdsCloudException("missing data points"); + } - if (points == null) { - if (getThing().getStatus() == ThingStatus.ONLINE) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "cloud server has no info this device"); + if (!points.isOnline()) { + if (getThing().getStatus() == ThingStatus.ONLINE) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, + "cloud server reports device offline"); + } + return; } - return; - } - if (!points.isOnline()) { - if (getThing().getStatus() == ThingStatus.ONLINE) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, - "cloud server reports device offline"); + if (getThing().getStatus() != ThingStatus.ONLINE) { + updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "server response ok"); } - return; - } - if (getThing().getStatus() != ThingStatus.ONLINE) { - updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "received info from cloud server"); - } + for (ChannelMap channel : CHAN_MAP) { + if (!debouncer.timeExpired(channel.id)) { + continue; + } - for (ChannelMap chan : CHAN_MAP) { - if (debouncer.timeExpired(chan.channelId)) { + BasePoint point = points.getPointByClass(channel.clazz); State state = null; - switch (chan.channelId) { + switch (channel.id) { case CHA_ROOM_TEMP: case CHA_ROOM_HUMIDITY: case CHA_OUTSIDE_TEMP: case CHA_TARGET_TEMP: { - state = points.getRaw(chan.hierarchyName); + state = point.getState(); break; } case CHA_ROOM_AIR_QUALITY: case CHA_ENERGY_SAVINGS_LEVEL: { - state = points.getEnum(chan.hierarchyName); + state = point.getEnum(); break; } case CHA_OUTPUT_STATE: { - state = points.getEnum(chan.hierarchyName); - /* - * convert the state text "Neither" to the more easy to understand word "Off" - */ - if (state.toString().equals(STATE_NEITHER)) { + state = point.getEnum(); + // convert the state text "Neither" to the easier to understand word "Off" + if (STATE_NEITHER.equals(state.toString())) { state = new StringType(STATE_OFF); } break; } case CHA_STAT_AUTO_MODE: { - state = OnOffType.from(points.getPresPrio(chan.hierarchyName) > 13 - || points.asInt(HIE_STAT_OCC_MODE_PRESENT) == 2); + state = OnOffType.from(point.getPresentPriority() > 13 + || points.getPointByClass(HIE_STAT_OCC_MODE_PRESENT).asInt() == 2); break; } case CHA_STAT_OCC_MODE_PRESENT: { - state = OnOffType.from(points.asInt(chan.hierarchyName) == 3); + state = OnOffType.from(point.asInt() == 3); break; } case CHA_DHW_AUTO_MODE: { - state = OnOffType.from(points.getPresPrio(chan.hierarchyName) > 13); + state = OnOffType.from(point.getPresentPriority() > 13); break; } case CHA_DHW_OUTPUT_STATE: { - state = OnOffType.from(points.asInt(chan.hierarchyName) == 2); + state = OnOffType.from(point.asInt() == 2); break; } } if (state != null) { - updateState(chan.channelId, state); + updateState(channel.id, state); } } + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "doPollNow()", e.getClass().getName(), e.getMessage()); } } @@ -275,18 +291,34 @@ private void doPollNow() { * private method: sends a new channel value to the cloud server */ private synchronized void doHandleCommand(String channelId, Command command) { - RdsCloudHandler cloud = getCloudHandler(); - if (cloud != null && points == null) { - points = RdsDataPoints.create(cloud.getApiKey(), cloud.getToken(), config.plantId); - } + RdsDataPoints points = this.points; + try { + RdsCloudHandler cloud = getCloudHandler(); + + String apiKey = cloud.getApiKey(); + String token = cloud.getToken(); - if (points != null && cloud != null) { - for (ChannelMap chan : CHAN_MAP) { - if (channelId.equals(chan.channelId)) { - switch (chan.channelId) { + if ((points == null || (!points.refresh(apiKey, token)))) { + points = fetchPoints(); + } + + if (points == null) { + throw new RdsCloudException("missing data points"); + } + + for (ChannelMap channel : CHAN_MAP) { + if (channelId.equals(channel.id)) { + switch (channel.id) { case CHA_TARGET_TEMP: { - points.setValue(cloud.getApiKey(), cloud.getToken(), chan.hierarchyName, - command.format("%s")); + Command doCommand = command; + if (command instanceof QuantityType) { + Unit unit = points.getPointByClass(channel.clazz).getUnit(); + QuantityType temp = ((QuantityType) command).toUnit(unit); + if (temp != null) { + doCommand = temp; + } + } + points.setValue(apiKey, token, channel.clazz, doCommand.format("%s")); debouncer.initialize(channelId); break; } @@ -296,32 +328,30 @@ private synchronized void doHandleCommand(String channelId, Command command) { * use Comfort Button = 1 to set to Manual */ if (command == OnOffType.ON) { - points.setValue(cloud.getApiKey(), cloud.getToken(), HIE_ENERGY_SAVINGS_LEVEL, "5"); + points.setValue(apiKey, token, HIE_ENERGY_SAVINGS_LEVEL, "5"); } else { - points.setValue(cloud.getApiKey(), cloud.getToken(), HIE_STAT_CMF_BTN, "1"); + points.setValue(apiKey, token, HIE_STAT_CMF_BTN, "1"); } debouncer.initialize(channelId); break; } case CHA_STAT_OCC_MODE_PRESENT: { - points.setValue(cloud.getApiKey(), cloud.getToken(), chan.hierarchyName, - command == OnOffType.OFF ? "2" : "3"); + points.setValue(apiKey, token, channel.clazz, command == OnOffType.OFF ? "2" : "3"); debouncer.initialize(channelId); break; } case CHA_DHW_AUTO_MODE: { if (command == OnOffType.ON) { - points.setValue(cloud.getApiKey(), cloud.getToken(), chan.hierarchyName, "0"); + points.setValue(apiKey, token, channel.clazz, "0"); } else { - points.setValue(cloud.getApiKey(), cloud.getToken(), chan.hierarchyName, - String.valueOf(points.asInt(chan.hierarchyName))); + points.setValue(apiKey, token, channel.clazz, + Integer.toString(points.getPointByClass(channel.clazz).asInt())); } debouncer.initialize(channelId); break; } case CHA_DHW_OUTPUT_STATE: { - points.setValue(cloud.getApiKey(), cloud.getToken(), chan.hierarchyName, - command == OnOffType.OFF ? "1" : "2"); + points.setValue(apiKey, token, channel.clazz, command == OnOffType.OFF ? "1" : "2"); debouncer.initialize(channelId); break; } @@ -330,20 +360,22 @@ private synchronized void doHandleCommand(String channelId, Command command) { case CHA_OUTSIDE_TEMP: case CHA_ROOM_AIR_QUALITY: case CHA_OUTPUT_STATE: { - logger.debug("error: unexpected command to channel {}", chan.channelId); + logger.debug("error: unexpected command to channel {}", channel.id); break; } } break; } } + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "doHandleCommand()", e.getClass().getName(), e.getMessage()); } } /* * private method: returns the cloud server handler */ - private RdsCloudHandler getCloudHandler() { + private RdsCloudHandler getCloudHandler() throws RdsCloudException { @Nullable Bridge b; @@ -353,7 +385,47 @@ private RdsCloudHandler getCloudHandler() { if ((b = getBridge()) != null && (h = b.getHandler()) != null && h instanceof RdsCloudHandler) { return (RdsCloudHandler) h; } + throw new RdsCloudException("no cloud handler found"); + } - return null; + @Nullable + public RdsDataPoints fetchPoints() { + RdsConfiguration config = this.config; + try { + if (config == null) { + throw new RdsCloudException("missing configuration"); + } + + String url = String.format(URL_POINTS, config.plantId); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_HTTP_COMMAND, HTTP_GET, url.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_HTTP_COMMAND_ABR, HTTP_GET, url.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_SENDING_MARK, url.substring(0, Math.min(url.length(), 30))); + } + + RdsCloudHandler cloud = getCloudHandler(); + String apiKey = cloud.getApiKey(); + String token = cloud.getToken(); + + String json = RdsDataPoints.httpGenericGetJson(apiKey, token, url); + + if (logger.isTraceEnabled()) { + logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length()); + logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json); + } else if (logger.isDebugEnabled()) { + logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length()); + logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK, json.substring(0, Math.min(json.length(), 30))); + } + + return this.points = RdsDataPoints.createFromJson(json); + } catch (RdsCloudException e) { + logger.warn(LOG_SYSTEM_EXCEPTION, "fetchPoints()", e.getClass().getName(), e.getMessage()); + } catch (JsonParseException | IOException e) { + logger.warn(LOG_RUNTIME_EXCEPTION, "fetchPoints()", e.getClass().getName(), e.getMessage()); + } + return this.points = null; } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java index 1266ff2fc9ea8..67b8030f6c326 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.config.discovery.DiscoveryService; import org.eclipse.smarthome.core.thing.Bridge; @@ -39,6 +40,7 @@ * * @author Andrew Fiddian-Green - Initial contribution */ +@NonNullByDefault @Component(configurationPid = "binding.siemensrds", service = ThingHandlerFactory.class) public class RdsHandlerFactory extends BaseThingHandlerFactory { @@ -52,8 +54,9 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); } + @Nullable @Override - protected @Nullable ThingHandler createHandler(Thing thing) { + protected ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if ((thingTypeUID.equals(THING_TYPE_CLOUD)) && (thing instanceof Bridge)) { @@ -103,10 +106,13 @@ private synchronized void createDiscoveryService(RdsCloudHandler handler) { */ private synchronized void destroyDiscoveryService(RdsCloudHandler handler) { // fetch the respective thing's service registration from our list - ServiceRegistration serviceReg = discos.remove(handler.getThing().getUID()); + @Nullable + Object object = discos.remove(handler.getThing().getUID()); + + // retrieve the respective discovery service + if (object instanceof ServiceRegistration) { + ServiceRegistration serviceReg = (ServiceRegistration) object; - if (serviceReg != null) { - // retrieve the respective discovery service RdsDiscoveryService disco = (RdsDiscoveryService) bundleContext.getService(serviceReg.getReference()); // unregister the service diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java index 66c40a5c92d6c..ce281634891f8 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java @@ -12,17 +12,14 @@ */ package org.openhab.binding.siemensrds.internal; -import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.URL_PLANTS; - -import java.io.IOException; import java.util.List; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; /** @@ -32,48 +29,52 @@ * @author Andrew Fiddian-Green - Initial contribution * */ -class RdsPlants { +@NonNullByDefault +public class RdsPlants { - protected static final Logger LOGGER = LoggerFactory.getLogger(RdsPlants.class); + protected final Logger logger = LoggerFactory.getLogger(RdsPlants.class); + @Nullable @SerializedName("items") private List plants; private static final Gson GSON = new Gson(); - static class PlantInfo { + @SuppressWarnings("null") + @NonNullByDefault + public static class PlantInfo { + @Nullable @SerializedName("id") private String plantId; @SerializedName("isOnline") - private Boolean online; + private boolean online; - public String getId() { - return plantId; + public String getId() throws RdsCloudException { + String plantId = this.plantId; + if (plantId != null) { + return plantId; + } + throw new RdsCloudException("plant has no Id"); } - public Boolean isOnline() { + public boolean isOnline() { return online; } } /* - * public method: execute a GET on the cloud server, parse JSON, and create a - * class that encapsulates the data + * public method: parse JSON, and create a class that encapsulates the data */ - public static @Nullable RdsPlants create(String apiKey, String token) { - try { - String json = RdsDataPoints.httpGenericGetJson(apiKey, token, URL_PLANTS); - return GSON.fromJson(json, RdsPlants.class); - } catch (JsonSyntaxException | RdsCloudException | IOException e) { - LOGGER.warn("create {}: \"{}\"", e.getClass().getName(), e.getMessage()); - return null; - } + @Nullable + public static RdsPlants createFromJson(String json) { + return GSON.fromJson(json, RdsPlants.class); } /* * public method: return the plant list */ + @Nullable public List getPlants() { return plants; } 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 new file mode 100644 index 0000000000000..ca043d42e8ba3 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/BasePoint.java @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import javax.measure.Unit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.ImperialUnits; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.types.State; +import org.eclipse.smarthome.core.types.UnDefType; + +import com.google.gson.annotations.SerializedName; + +import tec.uom.se.AbstractUnit; +import tec.uom.se.unit.Units; + +/** + * private class: a generic data point + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public abstract class BasePoint { + /* + * note: temperature symbols with a degree sign: the MVN Spotless formatter + * trashes the "degree" (looks like *) symbol, so we must escape these symbols + * as octal \260 or unicode \u00B00 + */ + public static final String DEGREES_CELSIUS = "\260C"; + public static final String DEGREES_FAHRENHEIT = "\260F"; + public static final String DEGREES_KELVIN = "K"; + + public static final int UNDEFINED_VALUE = -1; + + @SerializedName("rep") + protected int rep; + @SerializedName("type") + protected int type; + @SerializedName("write") + protected boolean write; + @Nullable + @SerializedName("descr") + protected String descr; + @SerializedName("limits") + protected float @Nullable [] limits; + @Nullable + @SerializedName("descriptionName") + protected String descriptionName; + @Nullable + @SerializedName("objectName") + protected String objectName; + @Nullable + @SerializedName("memberName") + private String memberName; + @Nullable + @SerializedName("hierarchyName") + private String hierarchyName; + @SerializedName("translated") + protected boolean translated; + @SerializedName("presentPriority") + protected int presentPriority; + + @Nullable + private String @Nullable [] enumVals; + private boolean enumParsed = false; + protected boolean isEnum = false; + + /* + * initialize the enum value list + */ + private boolean initEnum() { + if (!enumParsed) { + String descr = this.descr; + if (descr != null && descr.contains("*")) { + enumVals = descr.split("\\*"); + isEnum = true; + } + } + enumParsed = true; + return isEnum; + } + + public int getPresentPriority() { + return presentPriority; + } + + /* + * abstract methods => MUST be overridden + */ + public abstract int asInt(); + + public void refreshValueFrom(BasePoint from) { + presentPriority = from.presentPriority; + } + + protected boolean isEnum() { + return (enumParsed ? isEnum : initEnum()); + } + + public State getEnum() { + if (isEnum()) { + int index = asInt(); + String[] enumVals = this.enumVals; + if (index >= 0 && enumVals != null && index < enumVals.length) { + return new StringType(enumVals[index]); + } + } + return UnDefType.NULL; + } + + /* + * property getter for openHAB State => MUST be overridden + */ + public State getState() { + return UnDefType.NULL; + } + + /* + * property getter for openHAB returns the Units of Measure of the point value + */ + public Unit getUnit() { + /* + * determine the Units of Measure if available; note that other possible units + * (Ampere, hours, milliseconds, minutes) are currently not implemented + */ + String descr = this.descr; + if (descr != null) { + if (DEGREES_CELSIUS.equals(descr)) { + return SIUnits.CELSIUS; + } else if (DEGREES_FAHRENHEIT.equals(descr)) { + return ImperialUnits.FAHRENHEIT; + } else if (DEGREES_KELVIN.equals(descr)) { + return Units.KELVIN; + } + } + return AbstractUnit.ONE; + } + + /* + * property getter for JSON => MAY be overridden + */ + 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); + } + } + } + } + return String.format("{\"value\":%s}", newVal); + } + + public String getMemberName() { + String memberName = this.memberName; + return memberName != null ? memberName : "undefined"; + } + + @Nullable + private String hierarchyNameSuffix() { + String fullHierarchyName = this.hierarchyName; + if (fullHierarchyName != null) { + int suffixPosition = fullHierarchyName.lastIndexOf("'"); + if (suffixPosition >= 0) { + return fullHierarchyName.substring(suffixPosition, fullHierarchyName.length()); + } + } + return fullHierarchyName; + } + + public String getPointClass() { + String shortHierarchyName = hierarchyNameSuffix(); + if (shortHierarchyName != null) { + return shortHierarchyName; + } + return "#".concat(getMemberName()); + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java new file mode 100644 index 0000000000000..fe5d5c01195c3 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.types.State; +import org.eclipse.smarthome.core.types.UnDefType; + +import com.google.gson.annotations.SerializedName; + +/** + * private class a data point where "value" is a nested JSON numeric element + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class NestedNumberPoint extends BasePoint { + @Nullable + @SerializedName("value") + protected NestedNumberValue inner; + + @Override + public int asInt() { + NestedNumberValue inner = this.inner; + if (inner != null) { + Number innerValue = inner.value; + if (innerValue != null) { + return innerValue.intValue(); + } + } + return UNDEFINED_VALUE; + } + + @Override + public State getState() { + NestedNumberValue inner = this.inner; + if (inner != null) { + Number innerValue = inner.value; + if (innerValue != null) { + return new QuantityType<>(innerValue.doubleValue(), getUnit()); + } + } + return UnDefType.NULL; + } + + @Override + public int getPresentPriority() { + NestedNumberValue inner = this.inner; + return inner != null ? inner.presentPriority : UNDEFINED_VALUE; + } + + public void setPresentPriority(int value) { + NestedNumberValue inner = this.inner; + if (inner != null) { + inner.presentPriority = value; + } + } + + @Override + public void refreshValueFrom(BasePoint from) { + super.refreshValueFrom(from); + if (from instanceof NestedNumberPoint) { + NestedNumberValue fromInner = ((NestedNumberPoint) from).inner; + NestedNumberValue thisInner = this.inner; + if (thisInner != null && fromInner != null) { + thisInner.value = fromInner.value; + thisInner.presentPriority = fromInner.presentPriority; + } + } + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java new file mode 100644 index 0000000000000..64d8a6aed0858 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * private class inner (helper) class for an embedded JSON numeric element + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class NestedNumberValue { + @Nullable + @SerializedName("value") + protected Number value; + @SerializedName("presentPriority") + protected int presentPriority; +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java new file mode 100644 index 0000000000000..8655c6837a384 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.types.State; + +import com.google.gson.annotations.SerializedName; + +/** + * private class a data point where "value" is a JSON numeric element + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class NumberPoint extends BasePoint { + @Nullable + @SerializedName("value") + private Number value; + + @Override + public int asInt() { + Number value = this.value; + return value != null ? value.intValue() : UNDEFINED_VALUE; + } + + @Override + public State getState() { + Number value = this.value; + return value != null ? new DecimalType(value.doubleValue()) : new DecimalType(UNDEFINED_VALUE); + } + + @Override + public void refreshValueFrom(BasePoint from) { + super.refreshValueFrom(from); + if (from instanceof NumberPoint) { + this.value = ((NumberPoint) from).value; + } + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java new file mode 100644 index 0000000000000..2e8d0c8d09e73 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import java.lang.reflect.Type; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSyntaxException; + +/** + * private class a JSON de-serializer for the Data Point classes above + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public class PointDeserializer implements JsonDeserializer { + + private static enum PointType { + UNDEFINED, + STRING, + NESTED_NUMBER, + NUMBER + } + + @Override + public BasePoint deserialize(@Nullable JsonElement element, @Nullable Type guff, + @Nullable JsonDeserializationContext ctxt) throws JsonParseException { + if (element == null || ctxt == null) { + throw new JsonParseException("method called with null argument(s)"); + } + + JsonObject obj = element.getAsJsonObject(); + JsonElement value = obj.get("value"); + if (value == null) { + Object point = ctxt.deserialize(obj, UndefPoint.class); + if (point instanceof UndefPoint) { + return (UndefPoint) point; + } + throw new JsonSyntaxException("unable to parse point WITHOUT a \"value\" element"); + } + + PointType pointType = PointType.UNDEFINED; + + boolean valueIsPrimitive = value.isJsonPrimitive(); + + JsonElement rep = obj.get("rep"); + if (rep != null && rep.isJsonPrimitive() && rep.getAsJsonPrimitive().isNumber()) { + /* + * full point lists have a "rep" element so we know explicitly the point class + */ + int repValue = rep.getAsInt(); + if (repValue == 0) { + pointType = PointType.STRING; + } else if (repValue < 4) { + pointType = valueIsPrimitive ? PointType.NUMBER : PointType.NESTED_NUMBER; + } + } else { + /* + * refresh point lists do NOT have a "rep" element so try to infer the point + * class + */ + if (valueIsPrimitive) { + JsonPrimitive primitiveType = value.getAsJsonPrimitive(); + pointType = primitiveType.isString() ? PointType.STRING : PointType.NUMBER; + } else + pointType = PointType.NESTED_NUMBER; + } + + Object point; + switch (pointType) { + case STRING: { + point = ctxt.deserialize(obj, StringPoint.class); + if (point instanceof StringPoint) { + return (StringPoint) point; + } + break; + } + case NESTED_NUMBER: { + point = ctxt.deserialize(obj, NestedNumberPoint.class); + if (point instanceof NestedNumberPoint) { + return (NestedNumberPoint) point; + } + break; + } + case NUMBER: { + point = ctxt.deserialize(obj, NumberPoint.class); + if (point instanceof NumberPoint) { + return (NumberPoint) point; + } + break; + } + default: { + point = ctxt.deserialize(obj, UndefPoint.class); + if (point instanceof UndefPoint) { + return (UndefPoint) point; + } + } + } + throw new JsonSyntaxException("unable to parse point with a \"value\" element"); + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java new file mode 100644 index 0000000000000..c49a00ae50b60 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.types.State; + +import com.google.gson.annotations.SerializedName; + +/** + * private class a data point where "value" is a JSON text element + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class StringPoint extends BasePoint { + @Nullable + @SerializedName("value") + private String value; + + @Override + public int asInt() { + try { + return Integer.parseInt(value); + } catch (Exception e) { + return UNDEFINED_VALUE; + } + } + + @Override + public State getState() { + return new StringType(value); + } + + @Override + public void refreshValueFrom(BasePoint from) { + super.refreshValueFrom(from); + if (from instanceof StringPoint) { + this.value = ((StringPoint) from).value; + } + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/UndefPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/UndefPoint.java new file mode 100644 index 0000000000000..2f55c377147e1 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/UndefPoint.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.points; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.types.State; +import org.eclipse.smarthome.core.types.UnDefType; + +/** + * private class a data point where "value" is unknown + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class UndefPoint extends BasePoint { + + @Override + public State getState() { + return UnDefType.UNDEF; + } + + @Override + public int asInt() { + return UNDEFINED_VALUE; + } + + @Override + public void refreshValueFrom(BasePoint from) { + // do nothing + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.siemensrds/src/main/resources/ESH-INF/thing/thing-types.xml index f181240ef2021..e5b7d69b1c6f0 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/resources/ESH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.siemensrds/src/main/resources/ESH-INF/thing/thing-types.xml @@ -30,6 +30,7 @@ Time (seconds) between polling requests (min=8, max/default=60) 60 + true 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/RdsTestData.java new file mode 100644 index 0000000000000..d61b1dd3e2033 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/java/org/openhab/binding/siemensrds/test/RdsTestData.java @@ -0,0 +1,3416 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.siemensrds.test; + +import static org.junit.Assert.*; +import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.QuantityType; +import org.eclipse.smarthome.core.library.types.StringType; +import org.eclipse.smarthome.core.library.unit.ImperialUnits; +import org.eclipse.smarthome.core.library.unit.SIUnits; +import org.eclipse.smarthome.core.types.State; +import org.junit.Test; +import org.openhab.binding.siemensrds.internal.RdsAccessToken; +import org.openhab.binding.siemensrds.internal.RdsCloudException; +import org.openhab.binding.siemensrds.internal.RdsDataPoints; +import org.openhab.binding.siemensrds.internal.RdsPlants; +import org.openhab.binding.siemensrds.internal.RdsPlants.PlantInfo; +import org.openhab.binding.siemensrds.points.BasePoint; + +import tec.uom.se.unit.Units; + +/** + * test suite + * + * @author Andrew Fiddian-Green - Initial contribution + * + */ +@NonNullByDefault +public class RdsTestData { + + /* + * note: temperature symbols with a degree sign: the MVN Spotless formatter + * trashes the "degree" (looks like *) symbol, so we must escape these symbols + * as octal \260 or unicode \u00B00 in the following JSON test strings + * + * note: (at)formatter on/off tags instruct spotless not to reformat the JSON, + * (and perhaps also attempt to stop it trashing the degree symbols - see above) + */ + //@formatter:off + private static final String DATAPOINTS_JSON_FULL_SET = + "{" + + " \"totalCount\": 67," + + " \"values\": {" + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00000C\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;\"," + + " \"descriptionName\": \"ApplicationSoftwareVersion\"," + + " \"objectName\": \"ApplicationSoftwareVersion\"," + + " \"memberName\": \"ApplicationSoftwareVersion\"," + + " \"hierarchyName\": \"ApplicationSoftwareVersion\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00001C\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"Device object\"," + + " \"descriptionName\": \"Device Description\"," + + " \"objectName\": \"Device Description\"," + + " \"memberName\": \"Description\"," + + " \"hierarchyName\": \"Device Description\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00002C\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"FW=02.32.02.27;SVS-300.1:SBC=13.22;I\"," + + " \"descriptionName\": \"FirmwareRevision\"," + + " \"objectName\": \"FirmwareRevision\"," + + " \"memberName\": \"FirmwareRevision\"," + + " \"hierarchyName\": \"FirmwareRevision\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000046\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"RDS110\"," + + " \"descriptionName\": \"ModelName\"," + + " \"objectName\": \"ModelName\"," + + " \"memberName\": \"ModelName\"," + + " \"hierarchyName\": \"ModelName\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000070\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 0," + + " \"limits\": [0.0, 5.0]," + + " \"descr\": \"operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress\"," + + " \"descriptionName\": \"SystemStatus\"," + + " \"objectName\": \"SystemStatus\"," + + " \"memberName\": \"SystemStatus\"," + + " \"hierarchyName\": \"SystemStatus\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000077\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 0," + + " \"descriptionName\": \"UtcOffset\"," + + " \"objectName\": \"UtcOffset\"," + + " \"memberName\": \"UtcOffset\"," + + " \"hierarchyName\": \"UtcOffset\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00009B\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 19," + + " \"descriptionName\": \"DatabaseRevision\"," + + " \"objectName\": \"DatabaseRevision\"," + + " \"memberName\": \"DatabaseRevision\"," + + " \"hierarchyName\": \"DatabaseRevision\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0000C4\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 0," + + " \"limits\": [0.0, 7.0]," + + " \"descr\": \"unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended\"," + + " \"descriptionName\": \"LastRestartReason\"," + + " \"objectName\": \"LastRestartReason\"," + + " \"memberName\": \"LastRestartReason\"," + + " \"hierarchyName\": \"LastRestartReason\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0012DB\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"MDL:ASN= RDS110;HW=0.2.0;\"," + + " \"descriptionName\": \"ModelInformation\"," + + " \"objectName\": \"ModelInformation\"," + + " \"memberName\": \"4827\"," + + " \"hierarchyName\": \"ModelInformation\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF001355\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 1," + + " \"limits\": [0.0, 26.0]," + + " \"descr\": \"-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR\"," + + " \"descriptionName\": \"Active SystemLanguge\"," + + " \"objectName\": \"Active SystemLanguge\"," + + " \"memberName\": \"4949\"," + + " \"hierarchyName\": \"Active SystemLanguge\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013B0\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 26," + + " \"limits\": [0.0, 72.0]," + + " \"descr\": \"GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington\"," + + " \"descriptionName\": \"TimeZone\"," + + " \"objectName\": \"TimeZone\"," + + " \"memberName\": \"5040\"," + + " \"hierarchyName\": \"TimeZone\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013EC\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"160100096D\"," + + " \"descriptionName\": \"SerialNumber\"," + + " \"objectName\": \"SerialNumber\"," + + " \"memberName\": \"5100\"," + + " \"hierarchyName\": \"SerialNumber\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013F4\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"'10010'B\"," + + " \"descriptionName\": \"Device Features\"," + + " \"objectName\": \"Device Features\"," + + " \"memberName\": \"5108\"," + + " \"hierarchyName\": \"Device Features\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!01D00000700001C\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": \"Upstairs\"," + + " \"descriptionName\": \"R(1)'Description\"," + + " \"objectName\": \"R(1)'Description\"," + + " \"memberName\": \"Description\"," + + " \"hierarchyName\": \"R(1)'Description\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130B\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"192.168.1.1\"," + + " \"descriptionName\": \"NwkPortIP'IP gefault gateway\"," + + " \"objectName\": \"NwkPortIP'IP gefault gateway\"," + + " \"memberName\": \"4875\"," + + " \"hierarchyName\": \"NwkPortIP'IP gefault gateway\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130C\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"255.255.255.0\"," + + " \"descriptionName\": \"NwkPortIP'IP subnet mask\"," + + " \"objectName\": \"NwkPortIP'IP subnet mask\"," + + " \"memberName\": \"4876\"," + + " \"hierarchyName\": \"NwkPortIP'IP subnet mask\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130D\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"192.168.1.42\"," + + " \"descriptionName\": \"NwkPortIP'IP address\"," + + " \"objectName\": \"NwkPortIP'IP address\"," + + " \"memberName\": \"4877\"," + + " \"hierarchyName\": \"NwkPortIP'IP address\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130E\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 47808," + + " \"descriptionName\": \"NwkPortIP'UDP Port\"," + + " \"objectName\": \"NwkPortIP'UDP Port\"," + + " \"memberName\": \"4878\"," + + " \"hierarchyName\": \"NwkPortIP'UDP Port\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000000001313\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"'F0C77F6C1895'H\"," + + " \"descriptionName\": \"NwkPortIP'BACnet MAC address\"," + + " \"objectName\": \"NwkPortIP'BACnet MAC address\"," + + " \"memberName\": \"4883\"," + + " \"hierarchyName\": \"NwkPortIP'BACnet MAC address\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001286\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"sth.connectivity.ccl-siemens.com\"," + + " \"descriptionName\": \"NwkPortCCL'Connection URI\"," + + " \"objectName\": \"NwkPortCCL'Connection URI\"," + + " \"memberName\": \"4742\"," + + " \"hierarchyName\": \"NwkPortCCL'Connection URI\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001287\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"this-is-not-a-valid-activation-key\"," + + " \"descriptionName\": \"NwkPortCCL'Activation Key\"," + + " \"objectName\": \"NwkPortCCL'Activation Key\"," + + " \"memberName\": \"4743\"," + + " \"hierarchyName\": \"NwkPortCCL'Activation Key\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001288\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 60," + + " \"descriptionName\": \"NwkPortCCL'Reconection delay\"," + + " \"objectName\": \"NwkPortCCL'Reconection delay\"," + + " \"memberName\": \"4744\"," + + " \"hierarchyName\": \"NwkPortCCL'Reconection delay\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdPerMin\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 0," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Item Updates per Minute\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdTotal\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 286849," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Item Updates Total\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Languages\": {" + + " \"rep\": 0," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": \"-;en\"," + + " \"limits\": [0.0, 1.0]," + + " \"objectName\": \"CSL-Config\"," + + " \"memberName\": \"Languages\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 1," + + " \"limits\": [0.0, 1.0]," + + " \"descr\": \"Offline*Online\"," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Online\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInPerMin\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 1473," + + " \"descr\": \"bytes\"," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Traffic Inbound per Minute\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInTotal\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 178130801," + + " \"descr\": \"bytes\"," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Traffic Inbound Total\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutPerMin\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 616," + + " \"descr\": \"bytes\"," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Traffic Outbound per Minute\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutTotal\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": 60624666," + + " \"descr\": \"bytes\"," + + " \"descriptionName\": \"Target\"," + + " \"objectName\": \"Target\"," + + " \"memberName\": \"Traffic Outbound Total\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 18.5519028," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": -50.0," + + " \"maxValue\": 80.0" + + " }," + + " \"limits\": [-50.0, 80.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Outside air temperature\"," + + " \"objectName\": \"R(1)'TOa\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'TOa\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000002000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 5.0" + + " }," + + " \"limits\": [0.0, 5.0]," + + " \"descr\": \"A\"," + + " \"descriptionName\": \"Heating device electrical load\"," + + " \"objectName\": \"R(1)'HDevElLd\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'HDevElLd\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00200007F000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 24.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 17," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Comfort heating setpoint\"," + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHCmf\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHCmf\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000080000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 24.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260F\"," + + " \"descriptionName\": \"Pre-comfort heating setpoint\"," + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPcf\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHPcf\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000081000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 16.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Economy heating setpoint\"," + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHEco\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHEco\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000082000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 6.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Protection heating setpoint\"," + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPrt\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'SpHPrt\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 24.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 15," + + " \"eventState\": 0," + + " \"minValue\": 6.0," + + " \"maxValue\": 35.0" + + " }," + + " \"limits\": [12.0, 35.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Room temperature setpoint\"," + + " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTR\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpTR\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000084000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 15," + + " \"eventState\": 0," + + " \"minValue\": -18.0," + + " \"maxValue\": 11.0" + + " }," + + " \"limits\": [-9.0, 14.0]," + + " \"descr\": \"K\"," + + " \"descriptionName\": \"Room temperature setpoint shift\"," + + " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTRShft\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpTRShft\"," + + " \"translated\": false," + + " \"resolution\": 0.10000000149011612" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 46.86865," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 100.0" + + " }," + + " \"limits\": [0.0, 100.0]," + + " \"descr\": \"%r.H.\"," + + " \"descriptionName\": \"Relative humidity for room\"," + + " \"objectName\": \"R(1)'RHvacCoo'RHuRel\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'RHuRel\"," + + " \"translated\": false," + + " \"resolution\": 1.0" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 23.761879," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Room temperature\"," + + " \"objectName\": \"R(1)'RHvacCoo'RTemp\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'RTemp\"," + + " \"translated\": false," + + " \"resolution\": 0.10000000149011612" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B2000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 35.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 50.0" + + " }," + + " \"limits\": [0.0, 50.0]," + + " \"descr\": \"\260C\"," + + " \"descriptionName\": \"Max. heating setpoint\"," + + " \"objectName\": \"R(1)'SpTRMaxHCmf\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'SpTRMaxHCmf\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B4000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 30.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 120.0" + + " }," + + " \"limits\": [0.0, 120.0]," + + " \"descr\": \"Unknown Unit(236)\"," + + " \"descriptionName\": \"Warm-up gradient\"," + + " \"objectName\": \"R(1)'WarmUpGrdnt\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'WarmUpGrdnt\"," + + " \"translated\": false," + + " \"resolution\": 5.0" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B5000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 1.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": -5.0," + + " \"maxValue\": 5.0" + + " }," + + " \"limits\": [-5.0, 5.0]," + + " \"descr\": \"K\"," + + " \"descriptionName\": \"Built-in temp. sensor adj.\"," + + " \"objectName\": \"R(1)'TRBltnMsvAdj\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'TRBltnMsvAdj\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CB000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 5.0" + + " }," + + " \"limits\": [0.0, 5.0]," + + " \"descr\": \"A\"," + + " \"descriptionName\": \"Q22/Q24 electrical load\"," + + " \"objectName\": \"R(1)'Q22Q24ElLd\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'Q22Q24ElLd\"," + + " \"translated\": false," + + " \"resolution\": 0.5" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CD000055\": {" + + " \"rep\": 1," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 713.0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 5000.0" + + " }," + + " \"limits\": [0.0, 5000.0]," + + " \"descr\": \"ppm\"," + + " \"descriptionName\": \"Room air quality\"," + + " \"objectName\": \"R(1)'RHvacCoo'RAQual\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'RAQual\"," + + " \"translated\": false," + + " \"resolution\": 100.0" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000038000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 13," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Inactive*Active*Null\"," + + " \"descriptionName\": \"Temporary comfort button\"," + + " \"objectName\": \"R(1)'ROpModDtr'TmpCmfBtn\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'TmpCmfBtn\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000039000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 13," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Inactive*Active*Null\"," + + " \"descriptionName\": \"Comfort button\"," + + " \"objectName\": \"R(1)'ROpModDtr'CmfBtn\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'CmfBtn\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003B000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Absent*Present*Null\"," + + " \"descriptionName\": \"Room presence detection\"," + + " \"objectName\": \"R(1)'RHvacCoo'RPscDet\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'RPscDet\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003F000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 1," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 17," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"No*Yes*Null\"," + + " \"descriptionName\": \"Enable heating control\"," + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'EnHCtl\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'EnHCtl\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000054000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 0," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Inactive*Active*Null\"," + + " \"descriptionName\": \"Room presence detector\"," + + " \"objectName\": \"R(1)'EnRPscDet\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'EnRPscDet\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300004C000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 2," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Null*Off*Protection\"," + + " \"descriptionName\": \"Off/protection configuration\"," + + " \"objectName\": \"R(1)'OffPrtCnf\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'OffPrtCnf\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 3," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 13," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 3.0]," + + " \"descr\": \"Null*Off*Absent*Present\"," + + " \"descriptionName\": \"Occupancy mode\"," + + " \"objectName\": \"R(1)'ROpModDtr'OccMod\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'OccMod\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 5," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 15," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 5.0]," + + " \"descr\": \"Null*Undefined*Poor*Satisfactory*Good*Excellent\"," + + " \"descriptionName\": \"Energy efficiency indication room\"," + + " \"objectName\": \"R(1)'RGrnLf'REei\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'REei\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 2," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 15," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Null*Off*On\"," + + " \"descriptionName\": \"Domestic hot water mode\"," + + " \"objectName\": \"R(1)'RHvacCoo'DhwOp'DhwMod\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwMod\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 2," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 3.0]," + + " \"descr\": \"Null*Neither*Heating*Cooling\"," + + " \"descriptionName\": \"Heating/cooling state\"," + + " \"objectName\": \"R(1)'RHvacCoo'HCStaDtr'HCSta\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'HCSta\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 4," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"presentPriority\": 15," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 4.0]," + + " \"descr\": \"Null*Protection*Economy*Pre-Comfort*Comfort\"," + + " \"descriptionName\": \"Present operating mode and reason\"," + + " \"objectName\": \"R(1)'RHvacCoo'PrOpModRsn\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'PrOpModRsn\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000071000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 6," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 6.0]," + + " \"descr\": \"Null*Default*Slow*Medium*Fast*2-position*Self-adaptive\"," + + " \"descriptionName\": \"Heating control loop\"," + + " \"objectName\": \"R(1)'HCtrSet\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'HCtrSet\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000072000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 2," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descr\": \"Null*Warm-up gradient*Self-adaptive\"," + + " \"descriptionName\": \"Optimum start control setting\"," + + " \"objectName\": \"R(1)'OsscSet\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'OsscSet\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055\": {" + + " \"rep\": 3," + + " \"type\": 0," + + " \"write\": false," + + " \"value\": {" + + " \"value\": 4," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0" + + " }," + + " \"limits\": [0.0, 4.0]," + + " \"descr\": \"Null*Undefined*Poor*Okay*Good\"," + + " \"descriptionName\": \"Room air quality indication\"," + + " \"objectName\": \"R(1)'RHvacCoo'RAQualInd\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'RAQualInd\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000000000055\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 500," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 1.0," + + " \"maxValue\": 8760.0" + + " }," + + " \"limits\": [1.0, 8760.0]," + + " \"descr\": \"h\"," + + " \"descriptionName\": \"Pump/valve kick cycle\"," + + " \"objectName\": \"R(1)'KickCyc\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'KickCyc\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000001000055\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 180000," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 3600000.0" + + " }," + + " \"limits\": [0.0, 3600000.0]," + + " \"descr\": \"ms\"," + + " \"descriptionName\": \"DHW min. ON time\"," + + " \"objectName\": \"R(1)'BoDhwTiOnMin\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOnMin\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000002000055\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 180000," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 3600000.0" + + " }," + + " \"limits\": [0.0, 3600000.0]," + + " \"descr\": \"ms\"," + + " \"descriptionName\": \"DHW min. OFF time\"," + + " \"objectName\": \"R(1)'BoDhwTiOffMin\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOffMin\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000007000055\": {" + + " \"rep\": 2," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": 253140," + + " \"statusFlags\": 0," + + " \"reliability\": 0," + + " \"eventState\": 0," + + " \"minValue\": 0.0," + + " \"maxValue\": 4294967295.0" + + " }," + + " \"limits\": [0.0, 4294967295.0]," + + " \"descr\": \"min\"," + + " \"descriptionName\": \"Operating hours heating\"," + + " \"objectName\": \"R(1)'RHvacCoo'OphHCDtr'OphH\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'OphH\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000004000055\": {" + + " \"rep\": 8," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": {" + + " \"cmd\": \"Command\"," + + " \"cal\": null," + + " \"act\": 0," + + " \"null\": 3," + + " \"default\": 0," + + " \"schedStart\": 4294967295," + + " \"schedEnd\": 4294967295," + + " \"days\": [" + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " [" + + " [0, 3]," + + " [7687, 4]," + + " [7701, 3]" + + " ]," + + " []" + + " ]," + + " \"timeTillNextValue\": 632," + + " \"nextValue\": 3" + + " }," + + " \"statusFlags\": 0," + + " \"reliability\": 0" + + " }," + + " \"limits\": [0.0, 4.0]," + + " \"descriptionName\": \"Room operating mode scheduler\"," + + " \"objectName\": \"R(1)'CenOpMod'ROpModSched\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000005000055\": {" + + " \"rep\": 8," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": {" + + " \"cmd\": \"Command\"," + + " \"cal\": null," + + " \"act\": 0," + + " \"null\": 3," + + " \"default\": 0," + + " \"schedStart\": 4294967295," + + " \"schedEnd\": 4294967295," + + " \"days\": [" + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " [" + + " [0, 1]," + + " [8, 2]," + + " [11543, 1]" + + " ]," + + " []" + + " ]," + + " \"timeTillNextValue\": 767," + + " \"nextValue\": 1" + + " }," + + " \"statusFlags\": 0," + + " \"reliability\": 0" + + " }," + + " \"limits\": [0.0, 2.0]," + + " \"descriptionName\": \"Domestic hot water scheduler\"," + + " \"objectName\": \"R(1)'CenDhw'DhwSched\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000400004E\": {" + + " \"rep\": 9," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": {" + + " \"act\": 0," + + " \"rules\": [" + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]" + + " ]" + + " }," + + " \"statusFlags\": 0," + + " \"reliability\": 0" + + " }," + + " \"descriptionName\": \"Room operating mode scheduler\"," + + " \"objectName\": \"R(1)'CenOpMod'ROpModSched\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\"," + + " \"translated\": false" + + " }," + + " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000500004E\": {" + + " \"rep\": 9," + + " \"type\": 0," + + " \"write\": true," + + " \"value\": {" + + " \"value\": {" + + " \"act\": 0," + + " \"rules\": [" + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]," + + " [3, 4294967295, 4294967295, 4294967295]" + + " ]" + + " }," + + " \"statusFlags\": 0," + + " \"reliability\": 0" + + " }," + + " \"descriptionName\": \"Domestic hot water scheduler\"," + + " \"objectName\": \"R(1)'CenDhw'DhwSched\"," + + " \"memberName\": \"PresentValue\"," + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\"," + + " \"translated\": false" + + " }" + + " }" + + "}"; + //@formatter:on + + //@formatter:off + private static final String DATAPOINTS_JSON_FULL_SET_NEW = + "{\r\n" + + " \"totalCount\": 70,\r\n" + + " \"values\": {\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00000C\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;\",\r\n" + + " \"descriptionName\": \"ApplicationSoftwareVersion\",\r\n" + + " \"objectName\": \"ApplicationSoftwareVersion\",\r\n" + + " \"memberName\": \"ApplicationSoftwareVersion\",\r\n" + + " \"hierarchyName\": \"ApplicationSoftwareVersion\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00001C\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"Device object\",\r\n" + + " \"descriptionName\": \"Device Description\",\r\n" + + " \"objectName\": \"Device Description\",\r\n" + + " \"memberName\": \"Description\",\r\n" + + " \"hierarchyName\": \"Device Description\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00002C\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"FW=02.32.02.27;SVS-300.1:SBC=13.22;I\",\r\n" + + " \"descriptionName\": \"FirmwareRevision\",\r\n" + + " \"objectName\": \"FirmwareRevision\",\r\n" + + " \"memberName\": \"FirmwareRevision\",\r\n" + + " \"hierarchyName\": \"FirmwareRevision\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000046\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"RDS110\",\r\n" + + " \"descriptionName\": \"ModelName\",\r\n" + + " \"objectName\": \"ModelName\",\r\n" + + " \"memberName\": \"ModelName\",\r\n" + + " \"hierarchyName\": \"ModelName\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000070\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 0,\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 5\r\n" + + " ],\r\n" + + " \"descr\": \"operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress\",\r\n" + + " \"descriptionName\": \"SystemStatus\",\r\n" + + " \"objectName\": \"SystemStatus\",\r\n" + + " \"memberName\": \"SystemStatus\",\r\n" + + " \"hierarchyName\": \"SystemStatus\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000077\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 0,\r\n" + + " \"descriptionName\": \"UtcOffset\",\r\n" + + " \"objectName\": \"UtcOffset\",\r\n" + + " \"memberName\": \"UtcOffset\",\r\n" + + " \"hierarchyName\": \"UtcOffset\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00009B\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 29,\r\n" + + " \"descriptionName\": \"DatabaseRevision\",\r\n" + + " \"objectName\": \"DatabaseRevision\",\r\n" + + " \"memberName\": \"DatabaseRevision\",\r\n" + + " \"hierarchyName\": \"DatabaseRevision\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0000C4\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 4,\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 7\r\n" + + " ],\r\n" + + " \"descr\": \"unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended\",\r\n" + + " \"descriptionName\": \"LastRestartReason\",\r\n" + + " \"objectName\": \"LastRestartReason\",\r\n" + + " \"memberName\": \"LastRestartReason\",\r\n" + + " \"hierarchyName\": \"LastRestartReason\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0012DB\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"MDL:ASN= RDS110;HW=0.2.0;\",\r\n" + + " \"descriptionName\": \"ModelInformation\",\r\n" + + " \"objectName\": \"ModelInformation\",\r\n" + + " \"memberName\": \"4827\",\r\n" + + " \"hierarchyName\": \"ModelInformation\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF001355\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 1,\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 26\r\n" + + " ],\r\n" + + " \"descr\": \"-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR\",\r\n" + + " \"descriptionName\": \"Active SystemLanguge\",\r\n" + + " \"objectName\": \"Active SystemLanguge\",\r\n" + + " \"memberName\": \"4949\",\r\n" + + " \"hierarchyName\": \"Active SystemLanguge\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013B0\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 26,\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 72\r\n" + + " ],\r\n" + + " \"descr\": \"GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington\",\r\n" + + " \"descriptionName\": \"TimeZone\",\r\n" + + " \"objectName\": \"TimeZone\",\r\n" + + " \"memberName\": \"5040\",\r\n" + + " \"hierarchyName\": \"TimeZone\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013EC\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"160100078A\",\r\n" + + " \"descriptionName\": \"SerialNumber\",\r\n" + + " \"objectName\": \"SerialNumber\",\r\n" + + " \"memberName\": \"5100\",\r\n" + + " \"hierarchyName\": \"SerialNumber\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013F4\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"'10010'B\",\r\n" + + " \"descriptionName\": \"Device Features\",\r\n" + + " \"objectName\": \"Device Features\",\r\n" + + " \"memberName\": \"5108\",\r\n" + + " \"hierarchyName\": \"Device Features\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!01D00000700001C\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"Downstairs\",\r\n" + + " \"descriptionName\": \"R(1)'Description\",\r\n" + + " \"objectName\": \"R(1)'Description\",\r\n" + + " \"memberName\": \"Description\",\r\n" + + " \"hierarchyName\": \"R(1)'Description\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130B\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"192.168.1.1\",\r\n" + + " \"descriptionName\": \"NwkPortIP'IP gefault gateway\",\r\n" + + " \"objectName\": \"NwkPortIP'IP gefault gateway\",\r\n" + + " \"memberName\": \"4875\",\r\n" + + " \"hierarchyName\": \"NwkPortIP'IP gefault gateway\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130C\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"255.255.255.0\",\r\n" + + " \"descriptionName\": \"NwkPortIP'IP subnet mask\",\r\n" + + " \"objectName\": \"NwkPortIP'IP subnet mask\",\r\n" + + " \"memberName\": \"4876\",\r\n" + + " \"hierarchyName\": \"NwkPortIP'IP subnet mask\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130D\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"192.168.1.41\",\r\n" + + " \"descriptionName\": \"NwkPortIP'IP address\",\r\n" + + " \"objectName\": \"NwkPortIP'IP address\",\r\n" + + " \"memberName\": \"4877\",\r\n" + + " \"hierarchyName\": \"NwkPortIP'IP address\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130E\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 47808,\r\n" + + " \"descriptionName\": \"NwkPortIP'UDP Port\",\r\n" + + " \"objectName\": \"NwkPortIP'UDP Port\",\r\n" + + " \"memberName\": \"4878\",\r\n" + + " \"hierarchyName\": \"NwkPortIP'UDP Port\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000000001313\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"'F0C77F6C10A1'H\",\r\n" + + " \"descriptionName\": \"NwkPortIP'BACnet MAC address\",\r\n" + + " \"objectName\": \"NwkPortIP'BACnet MAC address\",\r\n" + + " \"memberName\": \"4883\",\r\n" + + " \"hierarchyName\": \"NwkPortIP'BACnet MAC address\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001286\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"sth.connectivity.ccl-siemens.com\",\r\n" + + " \"descriptionName\": \"NwkPortCCL'Connection URI\",\r\n" + + " \"objectName\": \"NwkPortCCL'Connection URI\",\r\n" + + " \"memberName\": \"4742\",\r\n" + + " \"hierarchyName\": \"NwkPortCCL'Connection URI\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001287\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"HABEAS-XXQFD-JRHUP-YNAFG-FNE4Q\",\r\n" + + " \"descriptionName\": \"NwkPortCCL'Activation Key\",\r\n" + + " \"objectName\": \"NwkPortCCL'Activation Key\",\r\n" + + " \"memberName\": \"4743\",\r\n" + + " \"hierarchyName\": \"NwkPortCCL'Activation Key\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001288\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 60,\r\n" + + " \"descriptionName\": \"NwkPortCCL'Reconection delay\",\r\n" + + " \"objectName\": \"NwkPortCCL'Reconection delay\",\r\n" + + " \"memberName\": \"4744\",\r\n" + + " \"hierarchyName\": \"NwkPortCCL'Reconection delay\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdCurMon\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 3685,\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Item Updates Current Month\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdPerMin\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 1,\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Item Updates per Minute\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdTotal\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 429857,\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Item Updates Total\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Languages\": {\r\n" + + " \"rep\": 0,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": \"-;en\",\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " \"objectName\": \"CSL-Config\",\r\n" + + " \"memberName\": \"Languages\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Online\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 1,\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " \"descr\": \"Offline*Online\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Online\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInCurMon\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 6836970,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Inbound Current Month\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInPerMin\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 183,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Inbound per Minute\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInTotal\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 361410891,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Inbound Total\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutCurMon\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 1641440,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Outbound Current Month\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutPerMin\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 62,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Outbound per Minute\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutTotal\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": 105878276,\r\n" + + " \"descr\": \"bytes\",\r\n" + + " \"descriptionName\": \"Target\",\r\n" + + " \"objectName\": \"Target\",\r\n" + + " \"memberName\": \"Traffic Outbound Total\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00000000E000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 21.4816036,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": -50,\r\n" + + " \"maxValue\": 80\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " -50,\r\n" + + " 80\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Outside air temperature\",\r\n" + + " \"objectName\": \"R(1)'TOa\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'TOa\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00200007F000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 24,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 17,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Comfort heating setpoint\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHCmf\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHCmf\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000080000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 24,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Economy heating setpoint\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPcf\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHPcf\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000081000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 16,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Unoccupied heating setpoint\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHEco\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpHEco\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000082000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 6,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Protection heating setpoint\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPrt\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'SpHPrt\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000083000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 16,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 15,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 6,\r\n" + + " \"maxValue\": 35\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 6,\r\n" + + " 35\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Room temperature setpoint\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTR\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpTR\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000084000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 15,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": -10,\r\n" + + " \"maxValue\": 19\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " -18,\r\n" + + " 11\r\n" + + " ],\r\n" + + " \"descr\": \"K\",\r\n" + + " \"descriptionName\": \"Room temperature setpoint shift\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTRShft\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'SpTRShft\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.10000000149011612,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000085000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 36.1050224,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 100\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 100\r\n" + + " ],\r\n" + + " \"descr\": \"%r.H.\",\r\n" + + " \"descriptionName\": \"Relative humidity for room\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'RHuRel\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'RHuRel\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 1,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000086000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 24.2482586,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Room temperature\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'RTemp\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'RTemp\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.10000000149011612,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B2000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 35,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 50\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 50\r\n" + + " ],\r\n" + + " \"descr\": \"�C\",\r\n" + + " \"descriptionName\": \"Max. heating setpoint\",\r\n" + + " \"objectName\": \"R(1)'SpTRMaxHCmf\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'SpTRMaxHCmf\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B4000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 30,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 120\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 120\r\n" + + " ],\r\n" + + " \"descr\": \"Unknown Unit(236)\",\r\n" + + " \"descriptionName\": \"Warm-up gradient\",\r\n" + + " \"objectName\": \"R(1)'WarmUpGrdnt\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'WarmUpGrdnt\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B5000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 2,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": -5,\r\n" + + " \"maxValue\": 5\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " -5,\r\n" + + " 5\r\n" + + " ],\r\n" + + " \"descr\": \"K\",\r\n" + + " \"descriptionName\": \"Built-in temp. sensor adj.\",\r\n" + + " \"objectName\": \"R(1)'TRBltnMsvAdj\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'TRBltnMsvAdj\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000C6000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 5\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 5\r\n" + + " ],\r\n" + + " \"descr\": \"A\",\r\n" + + " \"descriptionName\": \"Heating device electrical load\",\r\n" + + " \"objectName\": \"R(1)'HDevElLd\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'HDevElLd\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CB000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 5\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 5\r\n" + + " ],\r\n" + + " \"descr\": \"A\",\r\n" + + " \"descriptionName\": \"Q22/Q24 electrical load\",\r\n" + + " \"objectName\": \"R(1)'Q22Q24ElLd\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'Q22Q24ElLd\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 0.5,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CD000055\": {\r\n" + + " \"rep\": 1,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 585.4,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 5000\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 5000\r\n" + + " ],\r\n" + + " \"descr\": \"ppm\",\r\n" + + " \"descriptionName\": \"Room air quality\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'RAQual\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'RAQual\",\r\n" + + " \"translated\": false,\r\n" + + " \"resolution\": 100,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000038000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 13,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Inactive*Active*Null\",\r\n" + + " \"descriptionName\": \"Temporary comfort button\",\r\n" + + " \"objectName\": \"R(1)'ROpModDtr'TmpCmfBtn\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'TmpCmfBtn\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000039000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 13,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Inactive*Active*Null\",\r\n" + + " \"descriptionName\": \"Comfort button\",\r\n" + + " \"objectName\": \"R(1)'ROpModDtr'CmfBtn\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'CmfBtn\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003B000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Absent*Present*Null\",\r\n" + + " \"descriptionName\": \"Room presence detection\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'RPscDet\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'RPscDet\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003F000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 1,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 17,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"No*Yes*Null\",\r\n" + + " \"descriptionName\": \"Enable heating control\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'TCtlH'EnHCtl\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'EnHCtl\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000054000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 0,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Inactive*Active*Null\",\r\n" + + " \"descriptionName\": \"Room presence detector\",\r\n" + + " \"objectName\": \"R(1)'EnRPscDet\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'EnRPscDet\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300004C000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 2,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Off*Protection\",\r\n" + + " \"descriptionName\": \"Off/protection configuration\",\r\n" + + " \"objectName\": \"R(1)'OffPrtCnf\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'OffPrtCnf\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000051000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 2,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 13,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Off*Absent*Present\",\r\n" + + " \"descriptionName\": \"Occupancy mode\",\r\n" + + " \"objectName\": \"R(1)'ROpModDtr'OccMod\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'OccMod\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000052000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 5,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 15,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 5\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Undefined*Poor*Satisfactory*Good*Excellent\",\r\n" + + " \"descriptionName\": \"Energy efficiency indication room\",\r\n" + + " \"objectName\": \"R(1)'RGrnLf'REei\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'REei\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000053000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 1,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 15,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Off*On\",\r\n" + + " \"descriptionName\": \"Domestic hot water mode\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'DhwOp'DhwMod\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwMod\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000056000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 1,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Neither*Heating*Cooling\",\r\n" + + " \"descriptionName\": \"Heating/cooling state\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'HCStaDtr'HCSta\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'HCSta\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300005A000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 2,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"presentPriority\": 13,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 4\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Protection*Unoccupied*Economy*Comfort\",\r\n" + + " \"descriptionName\": \"Present operating mode and reason\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'PrOpModRsn\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'PrOpModRsn\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000071000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 6,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 6\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Default*Slow*Medium*Fast*2-position*Self-adaptive\",\r\n" + + " \"descriptionName\": \"Heating control loop\",\r\n" + + " \"objectName\": \"R(1)'HCtrSet\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'HCtrSet\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000072000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 2,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Warm-up gradient*Self-adaptive\",\r\n" + + " \"descriptionName\": \"Optimum start control setting\",\r\n" + + " \"objectName\": \"R(1)'OsscSet\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'OsscSet\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000074000055\": {\r\n" + + " \"rep\": 3,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": false,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 4,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 4\r\n" + + " ],\r\n" + + " \"descr\": \"Null*Undefined*Poor*Okay*Good\",\r\n" + + " \"descriptionName\": \"Room air quality indication\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'RAQualInd\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'RAQualInd\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000000000055\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 500,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 1,\r\n" + + " \"maxValue\": 8760\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 1,\r\n" + + " 8760\r\n" + + " ],\r\n" + + " \"descr\": \"h\",\r\n" + + " \"descriptionName\": \"Pump/valve kick cycle\",\r\n" + + " \"objectName\": \"R(1)'KickCyc\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'KickCyc\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000001000055\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 180000,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 3600000\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 3600000\r\n" + + " ],\r\n" + + " \"descr\": \"ms\",\r\n" + + " \"descriptionName\": \"DHW min. ON time\",\r\n" + + " \"objectName\": \"R(1)'BoDhwTiOnMin\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOnMin\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000002000055\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 180000,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 3600000\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 3600000\r\n" + + " ],\r\n" + + " \"descr\": \"ms\",\r\n" + + " \"descriptionName\": \"DHW min. OFF time\",\r\n" + + " \"objectName\": \"R(1)'BoDhwTiOffMin\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOffMin\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000007000055\": {\r\n" + + " \"rep\": 2,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": 604800,\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0,\r\n" + + " \"eventState\": 0,\r\n" + + " \"minValue\": 0,\r\n" + + " \"maxValue\": 4294967295\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 4294967295\r\n" + + " ],\r\n" + + " \"descr\": \"min\",\r\n" + + " \"descriptionName\": \"Operating hours heating\",\r\n" + + " \"objectName\": \"R(1)'RHvacCoo'OphHCDtr'OphH\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'OphH\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000004000055\": {\r\n" + + " \"rep\": 8,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": {\r\n" + + " \"cmd\": \"Command\",\r\n" + + " \"cal\": null,\r\n" + + " \"act\": 0,\r\n" + + " \"null\": 3,\r\n" + + " \"default\": 0,\r\n" + + " \"schedStart\": 4294967295,\r\n" + + " \"schedEnd\": 4294967295,\r\n" + + " \"days\": [\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 3\r\n" + + " ],\r\n" + + " [\r\n" + + " 7687,\r\n" + + " 4\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 3\r\n" + + " ]\r\n" + + " ],\r\n" + + " []\r\n" + + " ],\r\n" + + " \"timeTillNextValue\": 509,\r\n" + + " \"nextValue\": 3\r\n" + + " },\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 4\r\n" + + " ],\r\n" + + " \"descriptionName\": \"Room operating mode scheduler\",\r\n" + + " \"objectName\": \"R(1)'CenOpMod'ROpModSched\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000005000055\": {\r\n" + + " \"rep\": 8,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"value\": {\r\n" + + " \"value\": {\r\n" + + " \"cmd\": \"Command\",\r\n" + + " \"cal\": null,\r\n" + + " \"act\": 0,\r\n" + + " \"null\": 3,\r\n" + + " \"default\": 0,\r\n" + + " \"schedStart\": 4294967295,\r\n" + + " \"schedEnd\": 4294967295,\r\n" + + " \"days\": [\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " [\r\n" + + " [\r\n" + + " 0,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 9,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7689,\r\n" + + " 1\r\n" + + " ],\r\n" + + " [\r\n" + + " 21,\r\n" + + " 2\r\n" + + " ],\r\n" + + " [\r\n" + + " 7701,\r\n" + + " 1\r\n" + + " ]\r\n" + + " ],\r\n" + + " []\r\n" + + " ],\r\n" + + " \"timeTillNextValue\": 479,\r\n" + + " \"nextValue\": 2\r\n" + + " },\r\n" + + " \"statusFlags\": 0,\r\n" + + " \"reliability\": 0\r\n" + + " },\r\n" + + " \"limits\": [\r\n" + + " 0,\r\n" + + " 2\r\n" + + " ],\r\n" + + " \"descriptionName\": \"Domestic hot water scheduler\",\r\n" + + " \"objectName\": \"R(1)'CenDhw'DhwSched\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000400004E\": {\r\n" + + " \"rep\": 9,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"descriptionName\": \"Room operating mode scheduler\",\r\n" + + " \"objectName\": \"R(1)'CenOpMod'ROpModSched\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " },\r\n" + + " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000500004E\": {\r\n" + + " \"rep\": 9,\r\n" + + " \"type\": 0,\r\n" + + " \"write\": true,\r\n" + + " \"webhookEnabled\": false,\r\n" + + " \"descriptionName\": \"Domestic hot water scheduler\",\r\n" + + " \"objectName\": \"R(1)'CenDhw'DhwSched\",\r\n" + + " \"memberName\": \"PresentValue\",\r\n" + + " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\",\r\n" + + " \"translated\": false,\r\n" + + " \"isVirtual\": false\r\n" + + " }\r\n" + + " }\r\n" + + "}"; + //@formatter:on + + //@formatter:off + private static final String DATAPOINTS_JSON_REFRESH_SET = + "{\"totalCount\":11," + + "\"values\":{" + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online\":{\"value\":1}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055\":{\"value\":{\"value\":12.6014862,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":-50.0,\"maxValue\":80.0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055\":{\"value\":{\"value\":16.0,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0,\"minValue\":6.0,\"maxValue\":35.0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055\":{\"value\":{\"value\":39.1304474,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":0.0,\"maxValue\":100.0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055\":{\"value\":{\"value\":21.51872,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":0.0,\"maxValue\":50.0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":13,\"eventState\":0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055\":{\"value\":{\"value\":5,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055\":{\"value\":{\"value\":1,\"statusFlags\":0,\"reliability\":0,\"eventState\":0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":13,\"eventState\":0}}," + + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055\":{\"value\":{\"value\":4,\"statusFlags\":0,\"reliability\":0,\"eventState\":0}}" + + "}" + + "}"; + //@formatter:on + + //@formatter:off + private static final String PLANTS_JSON = + "{" + + " \"totalCount\": 2," + + " \"items\": [{" + + " \"id\": \"Pd1774247-7de7-4896-ac76-b7e0dd943c40\"," + + " \"activationKey\": \"this-is-not-a-valid-activation-key\"," + + " \"address\": \"\"," + + " \"alarmStatus\": 0," + + " \"applicationSetDescription\": \"Siemens Smart Thermostat\\r\\nRDS110 => Device ID 45\\r\\n\"," + + " \"applicationSetId\": \"9964755b-6766-40bd-ba45-77b2446b71bb\"," + + " \"applicationSetName\": \"STH-Default-RDS110\"," + + " \"asn\": \"RDS110\"," + + " \"assigned\": true," + + " \"city\": \"\"," + + " \"country\": \"\"," + + " \"description\": \"\"," + + " \"energyIndicator\": 0," + + " \"isOnline\": true," + + " \"name\": \"this-is-not-a-valid-activation-key-RDS110\"," + + " \"phone\": \"\"," + + " \"serialNumber\": \"this-is-not-a-valid-activation-key\"," + + " \"state\": \"\"," + + " \"taskStatus\": 0," + + " \"tenant\": \"Siemens STH\"," + + " \"tenantId\": \"T290ea1c1-902c-4c0b-9dce-f96119bc7fc1\"," + + " \"timezone\": \"\"," + + " \"zipCode\": \"\"," + + " \"imsi\": \"\"," + + " \"customerPlantId\": null," + + " \"enhancedPrivileges\": false" + + " }, {" + + " \"id\": \"Pfaf770c8-abeb-4742-ad65-ead39030d369\"," + + " \"activationKey\": \"this-is-not-a-valid-activation-key\"," + + " \"address\": \"\"," + + " \"alarmStatus\": 0," + + " \"applicationSetDescription\": \"Siemens Smart Thermostat\\r\\nRDS110 => Device ID 45\\r\\n\"," + + " \"applicationSetId\": \"9964755b-6766-40bd-ba45-77b2446b71bb\"," + + " \"applicationSetName\": \"STH-Default-RDS110\"," + + " \"asn\": \"RDS110\"," + + " \"assigned\": true," + + " \"city\": \"\"," + + " \"country\": \"\"," + + " \"description\": \"\"," + + " \"energyIndicator\": 0," + + " \"isOnline\": true," + + " \"name\": \"this-is-not-a-valid-activation-key-RDS110\"," + + " \"phone\": \"\"," + + " \"serialNumber\": \"this-is-not-a-valid-activation-key\"," + + " \"state\": \"\"," + + " \"taskStatus\": 0," + + " \"tenant\": \"Siemens STH\"," + + " \"tenantId\": \"T290ea1c1-902c-4c0b-9dce-f96119bc7fc1\"," + + " \"timezone\": \"\"," + + " \"zipCode\": \"\"," + + " \"imsi\": \"\"," + + " \"customerPlantId\": null," + + " \"enhancedPrivileges\": false" + + " }]" + + "}"; + //@formatter:on + + //@formatter:off + private static final String ACCESS_TOKEN_JSON = + "{" + + " \"access_token\": \"this-is-not-a-valid-access_token\"," + + " \"token_type\": \"bearer\"," + + " \"expires_in\": 1209599," + + " \"userName\": \"software@whitebear.ch\"," + + " \".issued\": \"Thu, 06 Jun 2019 10:27:50 GMT\"," + + " \".expires\": \"Thu, 20 Jun 2019 10:27:50 GMT\"" + + "}"; + //@formatter:on + + @Test + public void test() { + confirmDegreeSymbolCodingNotTrashed(); + testAccessToken(); + testRdsPlants(); + testRdsDataPointsFull(); + testRdsDataPointsFullNew(); + testRdsDataPointsRefresh(); + } + + private void testRdsDataPointsFullNew() { + RdsDataPoints dataPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET_NEW); + assertNotNull(dataPoints); + try { + assertEquals("Downstairs", dataPoints.getDescription()); + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + + @Nullable + Map points = dataPoints.points; + assertNotNull(points); + assertEquals(70, points.size()); + } + + private void confirmDegreeSymbolCodingNotTrashed() { + /* + * note: temperature symbols with a degree sign: the MVN Spotless trashes the + * "degree" (looks like *) symbol, so we must escape these symbols as octal \260 + * or unicode \u00B00 - the following test will indicate is all is ok + */ + assertTrue("\260C".equals(BasePoint.DEGREES_CELSIUS)); + assertTrue("\u00B0C".equals(BasePoint.DEGREES_CELSIUS)); + assertTrue("\260F".equals(BasePoint.DEGREES_FAHRENHEIT)); + assertTrue("\u00B0F".equals(BasePoint.DEGREES_FAHRENHEIT)); + assertTrue(BasePoint.DEGREES_FAHRENHEIT.startsWith(BasePoint.DEGREES_CELSIUS.substring(0, 1))); + } + + private void testRdsDataPointsRefresh() { + RdsDataPoints refreshPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_REFRESH_SET); + assertNotNull(refreshPoints); + + assertNotNull(refreshPoints.points); + Map refreshMap = refreshPoints.points; + assertNotNull(refreshMap); + + @Nullable + BasePoint point; + State state; + + // check the parsed values + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), DecimalType.class); + assertEquals(1, ((DecimalType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(12.60, ((QuantityType) state).floatValue(), 0.01); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(16.0, ((QuantityType) state).floatValue(), 0.01); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(39.13, ((QuantityType) state).floatValue(), 0.01); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(21.51, ((QuantityType) state).floatValue(), 0.01); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(2, ((QuantityType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(5, ((QuantityType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(2, ((QuantityType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(1, ((QuantityType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(2, ((QuantityType) state).intValue()); + + point = refreshMap.get("Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055"); + assertTrue(point instanceof BasePoint); + state = point.getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(4, ((QuantityType) state).intValue()); + + RdsDataPoints originalPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET); + assertNotNull(originalPoints); + assertNotNull(originalPoints.points); + + // check that the refresh point types match the originals + Map originalMap = originalPoints.points; + assertNotNull(originalMap); + @Nullable + BasePoint refreshPoint; + @Nullable + BasePoint originalPoint; + for (String key : refreshMap.keySet()) { + refreshPoint = refreshMap.get(key); + assertTrue(refreshPoint instanceof BasePoint); + originalPoint = originalMap.get(key); + assertTrue(originalPoint instanceof BasePoint); + assertEquals(refreshPoint.getState().getClass(), originalPoint.getState().getClass()); + } + } + + private void testAccessToken() { + RdsAccessToken accessToken = RdsAccessToken.createFromJson(ACCESS_TOKEN_JSON); + assertNotNull(accessToken); + try { + assertEquals("this-is-not-a-valid-access_token", accessToken.getToken()); + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + assertTrue(accessToken.isExpired()); + } + + private void testRdsDataPointsFull() { + RdsDataPoints dataPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET); + assertNotNull(dataPoints); + try { + assertEquals("Upstairs", dataPoints.getDescription()); + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + + @Nullable + Map points = dataPoints.points; + assertNotNull(points); + assertEquals(67, points.size()); + + try { + assertEquals("AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;", + dataPoints.getPointByClass("ApplicationSoftwareVersion").getState().toString()); + assertEquals("Device object", dataPoints.getPointByClass("Device Description").getState().toString()); + assertEquals("FW=02.32.02.27;SVS-300.1:SBC=13.22;I", + dataPoints.getPointByClass("FirmwareRevision").getState().toString()); + assertEquals("RDS110", dataPoints.getPointByClass("ModelName").getState().toString()); + assertEquals(0, dataPoints.getPointByClass("SystemStatus").asInt()); + assertEquals(0, dataPoints.getPointByClass("UtcOffset").asInt()); + assertEquals(19, dataPoints.getPointByClass("DatabaseRevision").asInt()); + assertEquals(0, dataPoints.getPointByClass("LastRestartReason").asInt()); + assertEquals("MDL:ASN= RDS110;HW=0.2.0;", + dataPoints.getPointByClass("ModelInformation").getState().toString()); + assertEquals(1, dataPoints.getPointByClass("Active SystemLanguge").asInt()); + assertEquals(26, dataPoints.getPointByClass("TimeZone").asInt()); + assertEquals("160100096D", dataPoints.getPointByClass("SerialNumber").getState().toString()); + assertEquals("'10010'B", dataPoints.getPointByClass("Device Features").getState().toString()); + assertEquals("Upstairs", dataPoints.getPointByClass("'Description").getState().toString()); + assertEquals("192.168.1.1", dataPoints.getPointByClass("'IP gefault gateway").getState().toString()); + assertEquals("255.255.255.0", dataPoints.getPointByClass("'IP subnet mask").getState().toString()); + assertEquals("192.168.1.42", dataPoints.getPointByClass("'IP address").getState().toString()); + assertEquals(47808, dataPoints.getPointByClass("'UDP Port").asInt()); + assertEquals("'F0C77F6C1895'H", dataPoints.getPointByClass("'BACnet MAC address").getState().toString()); + assertEquals("sth.connectivity.ccl-siemens.com", + dataPoints.getPointByClass("'Connection URI").getState().toString()); + assertEquals("this-is-not-a-valid-activation-key", + dataPoints.getPointByClass("'Activation Key").getState().toString()); + assertEquals(60, dataPoints.getPointByClass("'Reconection delay").asInt()); + assertEquals(0, dataPoints.getPointByClass("#Item Updates per Minute").asInt()); + assertEquals(286849, dataPoints.getPointByClass("#Item Updates Total").asInt()); + assertEquals("-;en", dataPoints.getPointByClass("#Languages").getState().toString()); + assertEquals(1, dataPoints.getPointByClass("#Online").asInt()); + assertEquals(1473, dataPoints.getPointByClass("#Traffic Inbound per Minute").asInt()); + assertEquals(178130801, dataPoints.getPointByClass("#Traffic Inbound Total").asInt()); + assertEquals(616, dataPoints.getPointByClass("#Traffic Outbound per Minute").asInt()); + assertEquals(60624666, dataPoints.getPointByClass("#Traffic Outbound Total").asInt()); + assertEquals(0, dataPoints.getPointByClass("#Item Updates per Minute").asInt()); + + 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()); + + state = dataPoints.getPointByClass("'SpHPcf").getState(); + assertTrue(state instanceof QuantityType); + QuantityType fahrenheit = ((QuantityType) state).toUnit(ImperialUnits.FAHRENHEIT); + assertNotNull(fahrenheit); + assertEquals(24.00, fahrenheit.floatValue(), 0.01); + + state = dataPoints.getPointByClass("'SpHEco").getState(); + assertTrue(state instanceof QuantityType); + celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); + assertNotNull(celsius); + assertEquals(16.00, celsius.floatValue(), 0.01); + + state = dataPoints.getPointByClass("'SpHPrt").getState(); + assertTrue(state instanceof QuantityType); + celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); + assertNotNull(celsius); + assertEquals(6.00, celsius.floatValue(), 0.01); + + state = dataPoints.getPointByClass("'SpTR").getState(); + assertTrue(state instanceof QuantityType); + celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); + assertNotNull(celsius); + assertEquals(24.00, celsius.floatValue(), 0.01); + + state = dataPoints.getPointByClass("'SpTRShft").getState(); + assertTrue(state instanceof QuantityType); + QuantityType kelvin = ((QuantityType) state).toUnit(Units.KELVIN); + assertNotNull(kelvin); + assertEquals(0, kelvin.floatValue(), 0.01); + + assertEquals("46.86865", dataPoints.getPointByClass("'RHuRel").getState().toString()); + + state = dataPoints.getPointByClass("'RTemp").getState(); + assertTrue(state instanceof QuantityType); + celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); + assertNotNull(celsius); + assertEquals(23.76, celsius.floatValue(), 0.01); + + state = dataPoints.getPointByClass("'SpTRMaxHCmf").getState(); + assertTrue(state instanceof QuantityType); + celsius = ((QuantityType) state).toUnit(SIUnits.CELSIUS); + assertNotNull(celsius); + assertEquals(35.00, celsius.floatValue(), 0.01); + + assertEquals("30.0", dataPoints.getPointByClass("'WarmUpGrdnt").getState().toString()); + + state = dataPoints.getPointByClass("'TRBltnMsvAdj").getState(); + assertTrue(state instanceof QuantityType); + kelvin = ((QuantityType) state).toUnit(Units.KELVIN); + 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()); + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + + // test for a missing element + State test = null; + try { + test = dataPoints.getPointByClass("missing-element").getState(); + fail("expected exception did not occur"); + } catch (RdsCloudException e) { + assertEquals(null, test); + } + + try { + // test the all-the-way-round lookup loop + assertNotNull(dataPoints.points); + Map pointsMap = dataPoints.points; + assertNotNull(pointsMap); + @Nullable + Object point; + for (Entry entry : pointsMap.entrySet()) { + point = entry.getValue(); + assertTrue(point instanceof BasePoint); + // ignore UNDEF points where all-the-way-round lookup fails + if (!"UNDEF".equals(((BasePoint) point).getState().toString())) { + @Nullable + String x = entry.getKey(); + assertNotNull(x); + String y = ((BasePoint) point).getPointClass(); + String z = dataPoints.pointClassToId(y); + assertEquals(x, z); + } + } + + State state = null; + + // test the specific points that we use + state = dataPoints.getPointByClass(HIE_DESCRIPTION).getState(); + assertEquals("Upstairs", state.toString()); + + state = dataPoints.getPointByClass(HIE_ROOM_TEMP).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(23.761879, ((QuantityType) state).floatValue(), 0.01); + + state = dataPoints.getPointByClass(HIE_OUTSIDE_TEMP).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(18.55, ((QuantityType) state).floatValue(), 0.01); + + state = dataPoints.getPointByClass(HIE_TARGET_TEMP).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(24, ((QuantityType) state).floatValue(), 0.01); + + state = dataPoints.getPointByClass(HIE_ROOM_HUMIDITY).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(46.86, ((QuantityType) state).floatValue(), 0.01); + + state = dataPoints.getPointByClass(HIE_ROOM_AIR_QUALITY).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Good", state.toString()); + assertEquals("Good", dataPoints.getPointByClass(HIE_ROOM_AIR_QUALITY).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_ENERGY_SAVINGS_LEVEL).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Excellent", state.toString()); + assertEquals("Excellent", dataPoints.getPointByClass(HIE_ENERGY_SAVINGS_LEVEL).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_OUTPUT_STATE).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Heating", state.toString()); + assertEquals("Heating", dataPoints.getPointByClass(HIE_OUTPUT_STATE).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_STAT_OCC_MODE_PRESENT).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(3, ((QuantityType) state).intValue()); + assertEquals(3, dataPoints.getPointByClass(HIE_STAT_OCC_MODE_PRESENT).asInt()); + + state = dataPoints.getPointByClass(HIE_STAT_OCC_MODE_PRESENT).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Present", state.toString()); + assertEquals("Present", dataPoints.getPointByClass(HIE_STAT_OCC_MODE_PRESENT).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_DHW_OUTPUT_STATE).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(2, ((QuantityType) state).intValue()); + assertEquals(2, dataPoints.getPointByClass(HIE_DHW_OUTPUT_STATE).asInt()); + + state = dataPoints.getPointByClass(HIE_DHW_OUTPUT_STATE).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("On", state.toString()); + assertEquals("On", dataPoints.getPointByClass(HIE_DHW_OUTPUT_STATE).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_PR_OP_MOD_RSN).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(4, ((QuantityType) state).intValue()); + assertEquals(4, dataPoints.getPointByClass(HIE_PR_OP_MOD_RSN).asInt()); + + state = dataPoints.getPointByClass(HIE_PR_OP_MOD_RSN).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Comfort", state.toString()); + assertEquals("Comfort", dataPoints.getPointByClass(HIE_PR_OP_MOD_RSN).getEnum().toString()); + + state = dataPoints.getPointByClass(HIE_STAT_CMF_BTN).getState(); + assertEquals(state.getClass(), QuantityType.class); + assertEquals(0, ((QuantityType) state).intValue()); + assertEquals(0, dataPoints.getPointByClass(HIE_STAT_CMF_BTN).asInt()); + + state = dataPoints.getPointByClass(HIE_STAT_CMF_BTN).getEnum(); + assertEquals(state.getClass(), StringType.class); + assertEquals("Inactive", state.toString()); + assertEquals("Inactive", dataPoints.getPointByClass(HIE_STAT_CMF_BTN).getEnum().toString()); + + // test online code + assertTrue(dataPoints.isOnline()); + + // test present priority code + assertEquals(15, dataPoints.getPointByClass(HIE_TARGET_TEMP).getPresentPriority()); + + // test temperature units code (C) + BasePoint tempPoint = dataPoints.getPointByClass("'SpTR"); + assertTrue(tempPoint instanceof BasePoint); + assertEquals(SIUnits.CELSIUS, ((BasePoint) tempPoint).getUnit()); + + // test temperature units code (F) + tempPoint = dataPoints.getPointByClass("'SpHPcf"); + assertTrue(tempPoint instanceof BasePoint); + assertEquals(ImperialUnits.FAHRENHEIT, ((BasePoint) tempPoint).getUnit()); + + // test temperature units code (K) + tempPoint = dataPoints.getPointByClass("'SpHPcf"); + assertTrue(tempPoint instanceof BasePoint); + assertEquals(ImperialUnits.FAHRENHEIT, ((BasePoint) tempPoint).getUnit()); + + tempPoint = dataPoints.getPointByClass("'SpTRShft"); + assertTrue(tempPoint instanceof BasePoint); + assertEquals(Units.KELVIN, ((BasePoint) tempPoint).getUnit()); + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("null") + private void testRdsPlants() { + try { + RdsPlants plants = RdsPlants.createFromJson(PLANTS_JSON); + assertNotNull(plants); + + List plantList = plants.getPlants(); + assertNotNull(plantList); + + Object plant; + plant = plantList.get(0); + assertTrue(plant instanceof PlantInfo); + assertEquals("Pd1774247-7de7-4896-ac76-b7e0dd943c40", ((PlantInfo) plant).getId()); + assertTrue(((PlantInfo) plant).isOnline()); + + plant = plantList.get(1); + assertTrue(plant instanceof PlantInfo); + assertEquals("Pfaf770c8-abeb-4742-ad65-ead39030d369", ((PlantInfo) plant).getId()); + assertTrue(((PlantInfo) plant).isOnline()); + ; + } catch (RdsCloudException e) { + fail(e.getMessage()); + } + } +} From dfa93afd1e73eacc92f4648b83a10b2768b6ab2d Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Mon, 25 May 2020 18:03:27 +0100 Subject: [PATCH 2/4] [siemensrds] modifications requested in code review by @cpmeister Signed-off-by: Andrew Fiddian-Green --- .../org.openhab.binding.siemensrds/.classpath | 1 + .../org.openhab.binding.siemensrds/pom.xml | 4 +- .../siemensrds/internal/RdsAccessToken.java | 12 +- .../siemensrds/internal/RdsCloudHandler.java | 6 +- .../siemensrds/internal/RdsDataPoints.java | 10 +- .../siemensrds/internal/RdsDebouncer.java | 6 +- .../internal/RdsDiscoveryService.java | 7 +- .../siemensrds/internal/RdsHandler.java | 17 +- .../internal/RdsHandlerFactory.java | 11 +- .../siemensrds/internal/RdsPlants.java | 12 +- .../binding/siemensrds/points/BasePoint.java | 21 +- .../siemensrds/points/NestedNumberPoint.java | 4 +- .../siemensrds/points/NestedNumberValue.java | 3 +- .../siemensrds/points/NumberPoint.java | 4 +- .../siemensrds/points/StringPoint.java | 4 +- .../binding/siemensrds/test/RdsTestData.java | 2946 +---------------- .../src/test/resources/access_token.json | 8 + .../test/resources/datapoints_full_set.json | 1535 +++++++++ .../resources/datapoints_full_set_new.json | 1625 +++++++++ .../resources/datapoints_refresh_set.json | 101 + .../src/test/resources/plants.json | 61 + 21 files changed, 3398 insertions(+), 3000 deletions(-) create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/resources/access_token.json create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_refresh_set.json create mode 100644 bundles/org.openhab.binding.siemensrds/src/test/resources/plants.json diff --git a/bundles/org.openhab.binding.siemensrds/.classpath b/bundles/org.openhab.binding.siemensrds/.classpath index a5d95095ccaaf..28fd99941d198 100644 --- a/bundles/org.openhab.binding.siemensrds/.classpath +++ b/bundles/org.openhab.binding.siemensrds/.classpath @@ -18,6 +18,7 @@ + diff --git a/bundles/org.openhab.binding.siemensrds/pom.xml b/bundles/org.openhab.binding.siemensrds/pom.xml index ed63e6c3bb50a..cdb857d2dc1e8 100644 --- a/bundles/org.openhab.binding.siemensrds/pom.xml +++ b/bundles/org.openhab.binding.siemensrds/pom.xml @@ -1,4 +1,6 @@ - + + 4.0.0 diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java index 6107d90d60083..ea3c82d78617e 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsAccessToken.java @@ -54,15 +54,12 @@ public class RdsAccessToken { private static final Gson GSON = new Gson(); - @Nullable @SerializedName("access_token") - private String accessToken; - @Nullable + private @Nullable String accessToken; @SerializedName(".expires") - private String expires; + private @Nullable String expires; - @Nullable - private Date expDate = null; + private @Nullable Date expDate = null; /* * public static method: execute the HTTP POST on the server @@ -111,8 +108,7 @@ public static String httpGetTokenJson(String apiKey, String payload) throws RdsC /* * public method: parse the JSON, and create a class that encapsulates the data */ - @Nullable - public static RdsAccessToken createFromJson(String json) { + public static @Nullable RdsAccessToken createFromJson(String json) { return GSON.fromJson(json, RdsAccessToken.class); } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java index a084d4c490354..df1b5d1dddac5 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java @@ -41,11 +41,9 @@ public class RdsCloudHandler extends BaseBridgeHandler { private final Logger logger = LoggerFactory.getLogger(RdsCloudHandler.class); - @Nullable - private RdsCloudConfiguration config = null; + private @Nullable RdsCloudConfiguration config = null; - @Nullable - private RdsAccessToken accessToken = null; + private @Nullable RdsAccessToken accessToken = null; public RdsCloudHandler(Bridge bridge) { super(bridge); 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 42cab1b2c1cdd..5543dfa1de32b 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 @@ -64,12 +64,10 @@ public class RdsDataPoints { private static final Gson GSON = new GsonBuilder().registerTypeAdapter(BasePoint.class, new PointDeserializer()) .create(); - @Nullable @SerializedName("totalCount") - private String totalCount; - @Nullable + private @Nullable String totalCount; @SerializedName("values") - public Map points; + public @Nullable Map points; /* * this is a second index into to the points Map above; the purpose is to allow @@ -123,8 +121,7 @@ protected static String httpGenericGetJson(String apiKey, String token, String u * public static method: parse the JSON, and create a real instance of this * class that encapsulates the data data point values */ - @Nullable - public static RdsDataPoints createFromJson(String json) { + public static @Nullable RdsDataPoints createFromJson(String json) { return GSON.fromJson(json, RdsDataPoints.class); } @@ -241,7 +238,6 @@ public void setValue(String apiKey, String token, String pointClass, String valu } httpSetPointValueJson(apiKey, token, url, payload); - ; } catch (RdsCloudException e) { logger.warn(LOG_SYSTEM_EXCEPTION, "setValue()", e.getClass().getName(), e.getMessage()); } catch (JsonParseException | IOException e) { diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java index 94fa4c2a7b11b..0c2ac5ef0d152 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDebouncer.java @@ -30,7 +30,7 @@ @NonNullByDefault public class RdsDebouncer { - private final Map channels = new HashMap<>(); + private final Map channels = new HashMap<>(); @SuppressWarnings("null") @NonNullByDefault @@ -59,8 +59,8 @@ public void initialize(String channelId) { public Boolean timeExpired(String channelId) { if (channels.containsKey(channelId)) { @Nullable - Object debounceDelay = channels.get(channelId); - if (debounceDelay instanceof DebounceDelay) { + DebounceDelay debounceDelay = channels.get(channelId); + if (debounceDelay != null) { return ((DebounceDelay) debounceDelay).timeExpired(); } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java index 23612a390faf4..183abbc8edd84 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsDiscoveryService.java @@ -49,11 +49,9 @@ public class RdsDiscoveryService extends AbstractDiscoveryService { private final Logger logger = LoggerFactory.getLogger(RdsDiscoveryService.class); - @Nullable - private ScheduledFuture discoveryScheduler; + private @Nullable ScheduledFuture discoveryScheduler; - @Nullable - private RdsCloudHandler cloud; + private @Nullable RdsCloudHandler cloud; public static final Set DISCOVERABLE_THING_TYPES_UIDS = Collections .unmodifiableSet(Stream.of(THING_TYPE_RDS).collect(Collectors.toSet())); @@ -137,7 +135,6 @@ private void discoverPlants() { } plantClass = RdsPlants.createFromJson(json); - ; } catch (RdsCloudException e) { logger.warn(LOG_SYSTEM_EXCEPTION, "discoverPlants()", e.getClass().getName(), e.getMessage()); return; 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 6a2216c17be4d..1293344267612 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 @@ -55,21 +55,16 @@ public class RdsHandler extends BaseThingHandler { protected final Logger logger = LoggerFactory.getLogger(RdsHandler.class); - @Nullable - private ScheduledFuture lazyPollingScheduler = null; - - @Nullable - private ScheduledFuture fastPollingScheduler = null; + private @Nullable ScheduledFuture lazyPollingScheduler = null; + private @Nullable ScheduledFuture fastPollingScheduler = null; private final AtomicInteger fastPollingCallsToGo = new AtomicInteger(); private RdsDebouncer debouncer = new RdsDebouncer(); - @Nullable - private RdsConfiguration config = null; + private @Nullable RdsConfiguration config = null; - @Nullable - private RdsDataPoints points = null; + private @Nullable RdsDataPoints points = null; public RdsHandler(Thing thing) { super(thing); @@ -378,7 +373,6 @@ private synchronized void doHandleCommand(String channelId, Command command) { private RdsCloudHandler getCloudHandler() throws RdsCloudException { @Nullable Bridge b; - @Nullable BridgeHandler h; @@ -388,8 +382,7 @@ private RdsCloudHandler getCloudHandler() throws RdsCloudException { throw new RdsCloudException("no cloud handler found"); } - @Nullable - public RdsDataPoints fetchPoints() { + public @Nullable RdsDataPoints fetchPoints() { RdsConfiguration config = this.config; try { if (config == null) { diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java index 67b8030f6c326..c511dc14f12fd 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsHandlerFactory.java @@ -47,16 +47,15 @@ public class RdsHandlerFactory extends BaseThingHandlerFactory { private static final Set SUPPORTED_THING_TYPES_UIDS = Collections .unmodifiableSet(new HashSet<>(Arrays.asList(THING_TYPE_CLOUD, THING_TYPE_RDS))); - private final Map> discos = new HashMap<>(); + private final Map> discos = new HashMap<>(); @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); } - @Nullable @Override - protected ThingHandler createHandler(Thing thing) { + protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if ((thingTypeUID.equals(THING_TYPE_CLOUD)) && (thing instanceof Bridge)) { @@ -107,12 +106,10 @@ private synchronized void createDiscoveryService(RdsCloudHandler handler) { private synchronized void destroyDiscoveryService(RdsCloudHandler handler) { // fetch the respective thing's service registration from our list @Nullable - Object object = discos.remove(handler.getThing().getUID()); + ServiceRegistration serviceReg = discos.remove(handler.getThing().getUID()); // retrieve the respective discovery service - if (object instanceof ServiceRegistration) { - ServiceRegistration serviceReg = (ServiceRegistration) object; - + if (serviceReg != null) { RdsDiscoveryService disco = (RdsDiscoveryService) bundleContext.getService(serviceReg.getReference()); // unregister the service diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java index ce281634891f8..45c510cfe19e3 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsPlants.java @@ -34,9 +34,8 @@ public class RdsPlants { protected final Logger logger = LoggerFactory.getLogger(RdsPlants.class); - @Nullable @SerializedName("items") - private List plants; + private @Nullable List plants; private static final Gson GSON = new Gson(); @@ -44,9 +43,8 @@ public class RdsPlants { @NonNullByDefault public static class PlantInfo { - @Nullable @SerializedName("id") - private String plantId; + private @Nullable String plantId; @SerializedName("isOnline") private boolean online; @@ -66,16 +64,14 @@ public boolean isOnline() { /* * public method: parse JSON, and create a class that encapsulates the data */ - @Nullable - public static RdsPlants createFromJson(String json) { + public static @Nullable RdsPlants createFromJson(String json) { return GSON.fromJson(json, RdsPlants.class); } /* * public method: return the plant list */ - @Nullable - public List getPlants() { + public @Nullable List getPlants() { return plants; } } 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 ca043d42e8ba3..c45801dc6cade 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 @@ -52,30 +52,24 @@ public abstract class BasePoint { protected int type; @SerializedName("write") protected boolean write; - @Nullable @SerializedName("descr") - protected String descr; + protected @Nullable String descr; @SerializedName("limits") protected float @Nullable [] limits; - @Nullable @SerializedName("descriptionName") - protected String descriptionName; - @Nullable + protected @Nullable String descriptionName; @SerializedName("objectName") - protected String objectName; - @Nullable + protected @Nullable String objectName; @SerializedName("memberName") - private String memberName; - @Nullable + private @Nullable String memberName; @SerializedName("hierarchyName") - private String hierarchyName; + private @Nullable String hierarchyName; @SerializedName("translated") protected boolean translated; @SerializedName("presentPriority") protected int presentPriority; - @Nullable - private String @Nullable [] enumVals; + private @Nullable String @Nullable [] enumVals; private boolean enumParsed = false; protected boolean isEnum = false; @@ -172,8 +166,7 @@ public String getMemberName() { return memberName != null ? memberName : "undefined"; } - @Nullable - private String hierarchyNameSuffix() { + private @Nullable String hierarchyNameSuffix() { String fullHierarchyName = this.hierarchyName; if (fullHierarchyName != null) { int suffixPosition = fullHierarchyName.lastIndexOf("'"); diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java index fe5d5c01195c3..c5b9f1fdf9a41 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberPoint.java @@ -28,9 +28,9 @@ */ @NonNullByDefault public class NestedNumberPoint extends BasePoint { - @Nullable + @SerializedName("value") - protected NestedNumberValue inner; + protected @Nullable NestedNumberValue inner; @Override public int asInt() { diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java index 64d8a6aed0858..ec901876c3ff8 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NestedNumberValue.java @@ -25,9 +25,8 @@ */ @NonNullByDefault public class NestedNumberValue { - @Nullable @SerializedName("value") - protected Number value; + protected @Nullable Number value; @SerializedName("presentPriority") protected int presentPriority; } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java index 8655c6837a384..29dd2d5728c71 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/NumberPoint.java @@ -27,9 +27,9 @@ */ @NonNullByDefault public class NumberPoint extends BasePoint { - @Nullable + @SerializedName("value") - private Number value; + private @Nullable Number value; @Override public int asInt() { diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java index c49a00ae50b60..9580fe2f58686 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/StringPoint.java @@ -27,9 +27,9 @@ */ @NonNullByDefault public class StringPoint extends BasePoint { - @Nullable + @SerializedName("value") - private String value; + private @Nullable String value; @Override public int asInt() { 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/RdsTestData.java index d61b1dd3e2033..dd75d5335a4a8 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/RdsTestData.java @@ -15,6 +15,9 @@ import static org.junit.Assert.*; import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -46,2921 +49,20 @@ @NonNullByDefault public class RdsTestData { - /* - * note: temperature symbols with a degree sign: the MVN Spotless formatter - * trashes the "degree" (looks like *) symbol, so we must escape these symbols - * as octal \260 or unicode \u00B00 in the following JSON test strings - * - * note: (at)formatter on/off tags instruct spotless not to reformat the JSON, - * (and perhaps also attempt to stop it trashing the degree symbols - see above) - */ - //@formatter:off - private static final String DATAPOINTS_JSON_FULL_SET = - "{" + - " \"totalCount\": 67," + - " \"values\": {" + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00000C\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;\"," + - " \"descriptionName\": \"ApplicationSoftwareVersion\"," + - " \"objectName\": \"ApplicationSoftwareVersion\"," + - " \"memberName\": \"ApplicationSoftwareVersion\"," + - " \"hierarchyName\": \"ApplicationSoftwareVersion\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00001C\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"Device object\"," + - " \"descriptionName\": \"Device Description\"," + - " \"objectName\": \"Device Description\"," + - " \"memberName\": \"Description\"," + - " \"hierarchyName\": \"Device Description\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00002C\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"FW=02.32.02.27;SVS-300.1:SBC=13.22;I\"," + - " \"descriptionName\": \"FirmwareRevision\"," + - " \"objectName\": \"FirmwareRevision\"," + - " \"memberName\": \"FirmwareRevision\"," + - " \"hierarchyName\": \"FirmwareRevision\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000046\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"RDS110\"," + - " \"descriptionName\": \"ModelName\"," + - " \"objectName\": \"ModelName\"," + - " \"memberName\": \"ModelName\"," + - " \"hierarchyName\": \"ModelName\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000070\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 0," + - " \"limits\": [0.0, 5.0]," + - " \"descr\": \"operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress\"," + - " \"descriptionName\": \"SystemStatus\"," + - " \"objectName\": \"SystemStatus\"," + - " \"memberName\": \"SystemStatus\"," + - " \"hierarchyName\": \"SystemStatus\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000077\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 0," + - " \"descriptionName\": \"UtcOffset\"," + - " \"objectName\": \"UtcOffset\"," + - " \"memberName\": \"UtcOffset\"," + - " \"hierarchyName\": \"UtcOffset\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00009B\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 19," + - " \"descriptionName\": \"DatabaseRevision\"," + - " \"objectName\": \"DatabaseRevision\"," + - " \"memberName\": \"DatabaseRevision\"," + - " \"hierarchyName\": \"DatabaseRevision\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0000C4\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 0," + - " \"limits\": [0.0, 7.0]," + - " \"descr\": \"unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended\"," + - " \"descriptionName\": \"LastRestartReason\"," + - " \"objectName\": \"LastRestartReason\"," + - " \"memberName\": \"LastRestartReason\"," + - " \"hierarchyName\": \"LastRestartReason\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0012DB\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"MDL:ASN= RDS110;HW=0.2.0;\"," + - " \"descriptionName\": \"ModelInformation\"," + - " \"objectName\": \"ModelInformation\"," + - " \"memberName\": \"4827\"," + - " \"hierarchyName\": \"ModelInformation\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF001355\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 1," + - " \"limits\": [0.0, 26.0]," + - " \"descr\": \"-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR\"," + - " \"descriptionName\": \"Active SystemLanguge\"," + - " \"objectName\": \"Active SystemLanguge\"," + - " \"memberName\": \"4949\"," + - " \"hierarchyName\": \"Active SystemLanguge\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013B0\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 26," + - " \"limits\": [0.0, 72.0]," + - " \"descr\": \"GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington\"," + - " \"descriptionName\": \"TimeZone\"," + - " \"objectName\": \"TimeZone\"," + - " \"memberName\": \"5040\"," + - " \"hierarchyName\": \"TimeZone\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013EC\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"160100096D\"," + - " \"descriptionName\": \"SerialNumber\"," + - " \"objectName\": \"SerialNumber\"," + - " \"memberName\": \"5100\"," + - " \"hierarchyName\": \"SerialNumber\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013F4\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"'10010'B\"," + - " \"descriptionName\": \"Device Features\"," + - " \"objectName\": \"Device Features\"," + - " \"memberName\": \"5108\"," + - " \"hierarchyName\": \"Device Features\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!01D00000700001C\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": \"Upstairs\"," + - " \"descriptionName\": \"R(1)'Description\"," + - " \"objectName\": \"R(1)'Description\"," + - " \"memberName\": \"Description\"," + - " \"hierarchyName\": \"R(1)'Description\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130B\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"192.168.1.1\"," + - " \"descriptionName\": \"NwkPortIP'IP gefault gateway\"," + - " \"objectName\": \"NwkPortIP'IP gefault gateway\"," + - " \"memberName\": \"4875\"," + - " \"hierarchyName\": \"NwkPortIP'IP gefault gateway\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130C\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"255.255.255.0\"," + - " \"descriptionName\": \"NwkPortIP'IP subnet mask\"," + - " \"objectName\": \"NwkPortIP'IP subnet mask\"," + - " \"memberName\": \"4876\"," + - " \"hierarchyName\": \"NwkPortIP'IP subnet mask\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130D\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"192.168.1.42\"," + - " \"descriptionName\": \"NwkPortIP'IP address\"," + - " \"objectName\": \"NwkPortIP'IP address\"," + - " \"memberName\": \"4877\"," + - " \"hierarchyName\": \"NwkPortIP'IP address\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130E\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 47808," + - " \"descriptionName\": \"NwkPortIP'UDP Port\"," + - " \"objectName\": \"NwkPortIP'UDP Port\"," + - " \"memberName\": \"4878\"," + - " \"hierarchyName\": \"NwkPortIP'UDP Port\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000000001313\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"'F0C77F6C1895'H\"," + - " \"descriptionName\": \"NwkPortIP'BACnet MAC address\"," + - " \"objectName\": \"NwkPortIP'BACnet MAC address\"," + - " \"memberName\": \"4883\"," + - " \"hierarchyName\": \"NwkPortIP'BACnet MAC address\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001286\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"sth.connectivity.ccl-siemens.com\"," + - " \"descriptionName\": \"NwkPortCCL'Connection URI\"," + - " \"objectName\": \"NwkPortCCL'Connection URI\"," + - " \"memberName\": \"4742\"," + - " \"hierarchyName\": \"NwkPortCCL'Connection URI\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001287\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"this-is-not-a-valid-activation-key\"," + - " \"descriptionName\": \"NwkPortCCL'Activation Key\"," + - " \"objectName\": \"NwkPortCCL'Activation Key\"," + - " \"memberName\": \"4743\"," + - " \"hierarchyName\": \"NwkPortCCL'Activation Key\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001288\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 60," + - " \"descriptionName\": \"NwkPortCCL'Reconection delay\"," + - " \"objectName\": \"NwkPortCCL'Reconection delay\"," + - " \"memberName\": \"4744\"," + - " \"hierarchyName\": \"NwkPortCCL'Reconection delay\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdPerMin\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 0," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Item Updates per Minute\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdTotal\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 286849," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Item Updates Total\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Languages\": {" + - " \"rep\": 0," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": \"-;en\"," + - " \"limits\": [0.0, 1.0]," + - " \"objectName\": \"CSL-Config\"," + - " \"memberName\": \"Languages\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 1," + - " \"limits\": [0.0, 1.0]," + - " \"descr\": \"Offline*Online\"," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Online\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInPerMin\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 1473," + - " \"descr\": \"bytes\"," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Traffic Inbound per Minute\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInTotal\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 178130801," + - " \"descr\": \"bytes\"," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Traffic Inbound Total\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutPerMin\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 616," + - " \"descr\": \"bytes\"," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Traffic Outbound per Minute\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutTotal\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": 60624666," + - " \"descr\": \"bytes\"," + - " \"descriptionName\": \"Target\"," + - " \"objectName\": \"Target\"," + - " \"memberName\": \"Traffic Outbound Total\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 18.5519028," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": -50.0," + - " \"maxValue\": 80.0" + - " }," + - " \"limits\": [-50.0, 80.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Outside air temperature\"," + - " \"objectName\": \"R(1)'TOa\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'TOa\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000002000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 5.0" + - " }," + - " \"limits\": [0.0, 5.0]," + - " \"descr\": \"A\"," + - " \"descriptionName\": \"Heating device electrical load\"," + - " \"objectName\": \"R(1)'HDevElLd\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'HDevElLd\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00200007F000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 24.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 17," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Comfort heating setpoint\"," + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHCmf\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHCmf\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000080000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 24.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260F\"," + - " \"descriptionName\": \"Pre-comfort heating setpoint\"," + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPcf\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHPcf\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000081000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 16.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Economy heating setpoint\"," + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHEco\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHEco\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000082000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 6.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Protection heating setpoint\"," + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPrt\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'SpHPrt\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 24.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 15," + - " \"eventState\": 0," + - " \"minValue\": 6.0," + - " \"maxValue\": 35.0" + - " }," + - " \"limits\": [12.0, 35.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Room temperature setpoint\"," + - " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTR\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpTR\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000084000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 15," + - " \"eventState\": 0," + - " \"minValue\": -18.0," + - " \"maxValue\": 11.0" + - " }," + - " \"limits\": [-9.0, 14.0]," + - " \"descr\": \"K\"," + - " \"descriptionName\": \"Room temperature setpoint shift\"," + - " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTRShft\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpTRShft\"," + - " \"translated\": false," + - " \"resolution\": 0.10000000149011612" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 46.86865," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 100.0" + - " }," + - " \"limits\": [0.0, 100.0]," + - " \"descr\": \"%r.H.\"," + - " \"descriptionName\": \"Relative humidity for room\"," + - " \"objectName\": \"R(1)'RHvacCoo'RHuRel\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'RHuRel\"," + - " \"translated\": false," + - " \"resolution\": 1.0" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 23.761879," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Room temperature\"," + - " \"objectName\": \"R(1)'RHvacCoo'RTemp\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'RTemp\"," + - " \"translated\": false," + - " \"resolution\": 0.10000000149011612" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B2000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 35.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 50.0" + - " }," + - " \"limits\": [0.0, 50.0]," + - " \"descr\": \"\260C\"," + - " \"descriptionName\": \"Max. heating setpoint\"," + - " \"objectName\": \"R(1)'SpTRMaxHCmf\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'SpTRMaxHCmf\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B4000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 30.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 120.0" + - " }," + - " \"limits\": [0.0, 120.0]," + - " \"descr\": \"Unknown Unit(236)\"," + - " \"descriptionName\": \"Warm-up gradient\"," + - " \"objectName\": \"R(1)'WarmUpGrdnt\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'WarmUpGrdnt\"," + - " \"translated\": false," + - " \"resolution\": 5.0" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B5000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 1.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": -5.0," + - " \"maxValue\": 5.0" + - " }," + - " \"limits\": [-5.0, 5.0]," + - " \"descr\": \"K\"," + - " \"descriptionName\": \"Built-in temp. sensor adj.\"," + - " \"objectName\": \"R(1)'TRBltnMsvAdj\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'TRBltnMsvAdj\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CB000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 5.0" + - " }," + - " \"limits\": [0.0, 5.0]," + - " \"descr\": \"A\"," + - " \"descriptionName\": \"Q22/Q24 electrical load\"," + - " \"objectName\": \"R(1)'Q22Q24ElLd\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'Q22Q24ElLd\"," + - " \"translated\": false," + - " \"resolution\": 0.5" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CD000055\": {" + - " \"rep\": 1," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 713.0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 5000.0" + - " }," + - " \"limits\": [0.0, 5000.0]," + - " \"descr\": \"ppm\"," + - " \"descriptionName\": \"Room air quality\"," + - " \"objectName\": \"R(1)'RHvacCoo'RAQual\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'RAQual\"," + - " \"translated\": false," + - " \"resolution\": 100.0" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000038000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 13," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Inactive*Active*Null\"," + - " \"descriptionName\": \"Temporary comfort button\"," + - " \"objectName\": \"R(1)'ROpModDtr'TmpCmfBtn\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'TmpCmfBtn\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000039000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 13," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Inactive*Active*Null\"," + - " \"descriptionName\": \"Comfort button\"," + - " \"objectName\": \"R(1)'ROpModDtr'CmfBtn\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'CmfBtn\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003B000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Absent*Present*Null\"," + - " \"descriptionName\": \"Room presence detection\"," + - " \"objectName\": \"R(1)'RHvacCoo'RPscDet\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'RPscDet\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003F000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 1," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 17," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"No*Yes*Null\"," + - " \"descriptionName\": \"Enable heating control\"," + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'EnHCtl\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'EnHCtl\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000054000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 0," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Inactive*Active*Null\"," + - " \"descriptionName\": \"Room presence detector\"," + - " \"objectName\": \"R(1)'EnRPscDet\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'EnRPscDet\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300004C000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 2," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Null*Off*Protection\"," + - " \"descriptionName\": \"Off/protection configuration\"," + - " \"objectName\": \"R(1)'OffPrtCnf\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'OffPrtCnf\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 3," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 13," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 3.0]," + - " \"descr\": \"Null*Off*Absent*Present\"," + - " \"descriptionName\": \"Occupancy mode\"," + - " \"objectName\": \"R(1)'ROpModDtr'OccMod\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'OccMod\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 5," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 15," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 5.0]," + - " \"descr\": \"Null*Undefined*Poor*Satisfactory*Good*Excellent\"," + - " \"descriptionName\": \"Energy efficiency indication room\"," + - " \"objectName\": \"R(1)'RGrnLf'REei\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'REei\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 2," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 15," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Null*Off*On\"," + - " \"descriptionName\": \"Domestic hot water mode\"," + - " \"objectName\": \"R(1)'RHvacCoo'DhwOp'DhwMod\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwMod\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 2," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 3.0]," + - " \"descr\": \"Null*Neither*Heating*Cooling\"," + - " \"descriptionName\": \"Heating/cooling state\"," + - " \"objectName\": \"R(1)'RHvacCoo'HCStaDtr'HCSta\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'HCSta\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 4," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"presentPriority\": 15," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 4.0]," + - " \"descr\": \"Null*Protection*Economy*Pre-Comfort*Comfort\"," + - " \"descriptionName\": \"Present operating mode and reason\"," + - " \"objectName\": \"R(1)'RHvacCoo'PrOpModRsn\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'PrOpModRsn\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000071000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 6," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 6.0]," + - " \"descr\": \"Null*Default*Slow*Medium*Fast*2-position*Self-adaptive\"," + - " \"descriptionName\": \"Heating control loop\"," + - " \"objectName\": \"R(1)'HCtrSet\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'HCtrSet\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000072000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 2," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descr\": \"Null*Warm-up gradient*Self-adaptive\"," + - " \"descriptionName\": \"Optimum start control setting\"," + - " \"objectName\": \"R(1)'OsscSet\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'OsscSet\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055\": {" + - " \"rep\": 3," + - " \"type\": 0," + - " \"write\": false," + - " \"value\": {" + - " \"value\": 4," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0" + - " }," + - " \"limits\": [0.0, 4.0]," + - " \"descr\": \"Null*Undefined*Poor*Okay*Good\"," + - " \"descriptionName\": \"Room air quality indication\"," + - " \"objectName\": \"R(1)'RHvacCoo'RAQualInd\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'RAQualInd\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000000000055\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 500," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 1.0," + - " \"maxValue\": 8760.0" + - " }," + - " \"limits\": [1.0, 8760.0]," + - " \"descr\": \"h\"," + - " \"descriptionName\": \"Pump/valve kick cycle\"," + - " \"objectName\": \"R(1)'KickCyc\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'KickCyc\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000001000055\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 180000," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 3600000.0" + - " }," + - " \"limits\": [0.0, 3600000.0]," + - " \"descr\": \"ms\"," + - " \"descriptionName\": \"DHW min. ON time\"," + - " \"objectName\": \"R(1)'BoDhwTiOnMin\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOnMin\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000002000055\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 180000," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 3600000.0" + - " }," + - " \"limits\": [0.0, 3600000.0]," + - " \"descr\": \"ms\"," + - " \"descriptionName\": \"DHW min. OFF time\"," + - " \"objectName\": \"R(1)'BoDhwTiOffMin\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOffMin\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000007000055\": {" + - " \"rep\": 2," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": 253140," + - " \"statusFlags\": 0," + - " \"reliability\": 0," + - " \"eventState\": 0," + - " \"minValue\": 0.0," + - " \"maxValue\": 4294967295.0" + - " }," + - " \"limits\": [0.0, 4294967295.0]," + - " \"descr\": \"min\"," + - " \"descriptionName\": \"Operating hours heating\"," + - " \"objectName\": \"R(1)'RHvacCoo'OphHCDtr'OphH\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'OphH\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000004000055\": {" + - " \"rep\": 8," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": {" + - " \"cmd\": \"Command\"," + - " \"cal\": null," + - " \"act\": 0," + - " \"null\": 3," + - " \"default\": 0," + - " \"schedStart\": 4294967295," + - " \"schedEnd\": 4294967295," + - " \"days\": [" + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " [" + - " [0, 3]," + - " [7687, 4]," + - " [7701, 3]" + - " ]," + - " []" + - " ]," + - " \"timeTillNextValue\": 632," + - " \"nextValue\": 3" + - " }," + - " \"statusFlags\": 0," + - " \"reliability\": 0" + - " }," + - " \"limits\": [0.0, 4.0]," + - " \"descriptionName\": \"Room operating mode scheduler\"," + - " \"objectName\": \"R(1)'CenOpMod'ROpModSched\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000005000055\": {" + - " \"rep\": 8," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": {" + - " \"cmd\": \"Command\"," + - " \"cal\": null," + - " \"act\": 0," + - " \"null\": 3," + - " \"default\": 0," + - " \"schedStart\": 4294967295," + - " \"schedEnd\": 4294967295," + - " \"days\": [" + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " [" + - " [0, 1]," + - " [8, 2]," + - " [11543, 1]" + - " ]," + - " []" + - " ]," + - " \"timeTillNextValue\": 767," + - " \"nextValue\": 1" + - " }," + - " \"statusFlags\": 0," + - " \"reliability\": 0" + - " }," + - " \"limits\": [0.0, 2.0]," + - " \"descriptionName\": \"Domestic hot water scheduler\"," + - " \"objectName\": \"R(1)'CenDhw'DhwSched\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000400004E\": {" + - " \"rep\": 9," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": {" + - " \"act\": 0," + - " \"rules\": [" + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]" + - " ]" + - " }," + - " \"statusFlags\": 0," + - " \"reliability\": 0" + - " }," + - " \"descriptionName\": \"Room operating mode scheduler\"," + - " \"objectName\": \"R(1)'CenOpMod'ROpModSched\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\"," + - " \"translated\": false" + - " }," + - " \"Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000500004E\": {" + - " \"rep\": 9," + - " \"type\": 0," + - " \"write\": true," + - " \"value\": {" + - " \"value\": {" + - " \"act\": 0," + - " \"rules\": [" + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]," + - " [3, 4294967295, 4294967295, 4294967295]" + - " ]" + - " }," + - " \"statusFlags\": 0," + - " \"reliability\": 0" + - " }," + - " \"descriptionName\": \"Domestic hot water scheduler\"," + - " \"objectName\": \"R(1)'CenDhw'DhwSched\"," + - " \"memberName\": \"PresentValue\"," + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\"," + - " \"translated\": false" + - " }" + - " }" + - "}"; - //@formatter:on - - //@formatter:off - private static final String DATAPOINTS_JSON_FULL_SET_NEW = - "{\r\n" + - " \"totalCount\": 70,\r\n" + - " \"values\": {\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00000C\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;\",\r\n" + - " \"descriptionName\": \"ApplicationSoftwareVersion\",\r\n" + - " \"objectName\": \"ApplicationSoftwareVersion\",\r\n" + - " \"memberName\": \"ApplicationSoftwareVersion\",\r\n" + - " \"hierarchyName\": \"ApplicationSoftwareVersion\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00001C\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"Device object\",\r\n" + - " \"descriptionName\": \"Device Description\",\r\n" + - " \"objectName\": \"Device Description\",\r\n" + - " \"memberName\": \"Description\",\r\n" + - " \"hierarchyName\": \"Device Description\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00002C\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"FW=02.32.02.27;SVS-300.1:SBC=13.22;I\",\r\n" + - " \"descriptionName\": \"FirmwareRevision\",\r\n" + - " \"objectName\": \"FirmwareRevision\",\r\n" + - " \"memberName\": \"FirmwareRevision\",\r\n" + - " \"hierarchyName\": \"FirmwareRevision\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000046\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"RDS110\",\r\n" + - " \"descriptionName\": \"ModelName\",\r\n" + - " \"objectName\": \"ModelName\",\r\n" + - " \"memberName\": \"ModelName\",\r\n" + - " \"hierarchyName\": \"ModelName\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000070\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 0,\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 5\r\n" + - " ],\r\n" + - " \"descr\": \"operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress\",\r\n" + - " \"descriptionName\": \"SystemStatus\",\r\n" + - " \"objectName\": \"SystemStatus\",\r\n" + - " \"memberName\": \"SystemStatus\",\r\n" + - " \"hierarchyName\": \"SystemStatus\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000077\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 0,\r\n" + - " \"descriptionName\": \"UtcOffset\",\r\n" + - " \"objectName\": \"UtcOffset\",\r\n" + - " \"memberName\": \"UtcOffset\",\r\n" + - " \"hierarchyName\": \"UtcOffset\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00009B\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 29,\r\n" + - " \"descriptionName\": \"DatabaseRevision\",\r\n" + - " \"objectName\": \"DatabaseRevision\",\r\n" + - " \"memberName\": \"DatabaseRevision\",\r\n" + - " \"hierarchyName\": \"DatabaseRevision\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0000C4\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 4,\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 7\r\n" + - " ],\r\n" + - " \"descr\": \"unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended\",\r\n" + - " \"descriptionName\": \"LastRestartReason\",\r\n" + - " \"objectName\": \"LastRestartReason\",\r\n" + - " \"memberName\": \"LastRestartReason\",\r\n" + - " \"hierarchyName\": \"LastRestartReason\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0012DB\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"MDL:ASN= RDS110;HW=0.2.0;\",\r\n" + - " \"descriptionName\": \"ModelInformation\",\r\n" + - " \"objectName\": \"ModelInformation\",\r\n" + - " \"memberName\": \"4827\",\r\n" + - " \"hierarchyName\": \"ModelInformation\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF001355\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 1,\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 26\r\n" + - " ],\r\n" + - " \"descr\": \"-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR\",\r\n" + - " \"descriptionName\": \"Active SystemLanguge\",\r\n" + - " \"objectName\": \"Active SystemLanguge\",\r\n" + - " \"memberName\": \"4949\",\r\n" + - " \"hierarchyName\": \"Active SystemLanguge\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013B0\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 26,\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 72\r\n" + - " ],\r\n" + - " \"descr\": \"GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington\",\r\n" + - " \"descriptionName\": \"TimeZone\",\r\n" + - " \"objectName\": \"TimeZone\",\r\n" + - " \"memberName\": \"5040\",\r\n" + - " \"hierarchyName\": \"TimeZone\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013EC\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"160100078A\",\r\n" + - " \"descriptionName\": \"SerialNumber\",\r\n" + - " \"objectName\": \"SerialNumber\",\r\n" + - " \"memberName\": \"5100\",\r\n" + - " \"hierarchyName\": \"SerialNumber\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013F4\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"'10010'B\",\r\n" + - " \"descriptionName\": \"Device Features\",\r\n" + - " \"objectName\": \"Device Features\",\r\n" + - " \"memberName\": \"5108\",\r\n" + - " \"hierarchyName\": \"Device Features\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!01D00000700001C\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"Downstairs\",\r\n" + - " \"descriptionName\": \"R(1)'Description\",\r\n" + - " \"objectName\": \"R(1)'Description\",\r\n" + - " \"memberName\": \"Description\",\r\n" + - " \"hierarchyName\": \"R(1)'Description\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130B\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"192.168.1.1\",\r\n" + - " \"descriptionName\": \"NwkPortIP'IP gefault gateway\",\r\n" + - " \"objectName\": \"NwkPortIP'IP gefault gateway\",\r\n" + - " \"memberName\": \"4875\",\r\n" + - " \"hierarchyName\": \"NwkPortIP'IP gefault gateway\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130C\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"255.255.255.0\",\r\n" + - " \"descriptionName\": \"NwkPortIP'IP subnet mask\",\r\n" + - " \"objectName\": \"NwkPortIP'IP subnet mask\",\r\n" + - " \"memberName\": \"4876\",\r\n" + - " \"hierarchyName\": \"NwkPortIP'IP subnet mask\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130D\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"192.168.1.41\",\r\n" + - " \"descriptionName\": \"NwkPortIP'IP address\",\r\n" + - " \"objectName\": \"NwkPortIP'IP address\",\r\n" + - " \"memberName\": \"4877\",\r\n" + - " \"hierarchyName\": \"NwkPortIP'IP address\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130E\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 47808,\r\n" + - " \"descriptionName\": \"NwkPortIP'UDP Port\",\r\n" + - " \"objectName\": \"NwkPortIP'UDP Port\",\r\n" + - " \"memberName\": \"4878\",\r\n" + - " \"hierarchyName\": \"NwkPortIP'UDP Port\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000000001313\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"'F0C77F6C10A1'H\",\r\n" + - " \"descriptionName\": \"NwkPortIP'BACnet MAC address\",\r\n" + - " \"objectName\": \"NwkPortIP'BACnet MAC address\",\r\n" + - " \"memberName\": \"4883\",\r\n" + - " \"hierarchyName\": \"NwkPortIP'BACnet MAC address\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001286\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"sth.connectivity.ccl-siemens.com\",\r\n" + - " \"descriptionName\": \"NwkPortCCL'Connection URI\",\r\n" + - " \"objectName\": \"NwkPortCCL'Connection URI\",\r\n" + - " \"memberName\": \"4742\",\r\n" + - " \"hierarchyName\": \"NwkPortCCL'Connection URI\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001287\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"HABEAS-XXQFD-JRHUP-YNAFG-FNE4Q\",\r\n" + - " \"descriptionName\": \"NwkPortCCL'Activation Key\",\r\n" + - " \"objectName\": \"NwkPortCCL'Activation Key\",\r\n" + - " \"memberName\": \"4743\",\r\n" + - " \"hierarchyName\": \"NwkPortCCL'Activation Key\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001288\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 60,\r\n" + - " \"descriptionName\": \"NwkPortCCL'Reconection delay\",\r\n" + - " \"objectName\": \"NwkPortCCL'Reconection delay\",\r\n" + - " \"memberName\": \"4744\",\r\n" + - " \"hierarchyName\": \"NwkPortCCL'Reconection delay\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdCurMon\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 3685,\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Item Updates Current Month\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdPerMin\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 1,\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Item Updates per Minute\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdTotal\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 429857,\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Item Updates Total\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Languages\": {\r\n" + - " \"rep\": 0,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": \"-;en\",\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " \"objectName\": \"CSL-Config\",\r\n" + - " \"memberName\": \"Languages\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Online\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 1,\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " \"descr\": \"Offline*Online\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Online\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInCurMon\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 6836970,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Inbound Current Month\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInPerMin\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 183,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Inbound per Minute\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInTotal\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 361410891,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Inbound Total\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutCurMon\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 1641440,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Outbound Current Month\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutPerMin\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 62,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Outbound per Minute\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutTotal\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": 105878276,\r\n" + - " \"descr\": \"bytes\",\r\n" + - " \"descriptionName\": \"Target\",\r\n" + - " \"objectName\": \"Target\",\r\n" + - " \"memberName\": \"Traffic Outbound Total\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00000000E000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 21.4816036,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": -50,\r\n" + - " \"maxValue\": 80\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " -50,\r\n" + - " 80\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Outside air temperature\",\r\n" + - " \"objectName\": \"R(1)'TOa\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'TOa\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00200007F000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 24,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 17,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Comfort heating setpoint\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHCmf\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHCmf\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000080000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 24,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Economy heating setpoint\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPcf\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHPcf\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000081000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 16,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Unoccupied heating setpoint\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHEco\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpHEco\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000082000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 6,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Protection heating setpoint\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'SpHPrt\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'SpHPrt\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000083000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 16,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 15,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 6,\r\n" + - " \"maxValue\": 35\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 6,\r\n" + - " 35\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Room temperature setpoint\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTR\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpTR\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000084000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 15,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": -10,\r\n" + - " \"maxValue\": 19\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " -18,\r\n" + - " 11\r\n" + - " ],\r\n" + - " \"descr\": \"K\",\r\n" + - " \"descriptionName\": \"Room temperature setpoint shift\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'SpTRDtr'SpTRShft\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'SpTRShft\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.10000000149011612,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000085000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 36.1050224,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 100\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 100\r\n" + - " ],\r\n" + - " \"descr\": \"%r.H.\",\r\n" + - " \"descriptionName\": \"Relative humidity for room\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'RHuRel\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'RHuRel\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 1,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000086000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 24.2482586,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Room temperature\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'RTemp\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'RTemp\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.10000000149011612,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B2000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 35,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 50\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 50\r\n" + - " ],\r\n" + - " \"descr\": \"�C\",\r\n" + - " \"descriptionName\": \"Max. heating setpoint\",\r\n" + - " \"objectName\": \"R(1)'SpTRMaxHCmf\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'SpTRMaxHCmf\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B4000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 30,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 120\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 120\r\n" + - " ],\r\n" + - " \"descr\": \"Unknown Unit(236)\",\r\n" + - " \"descriptionName\": \"Warm-up gradient\",\r\n" + - " \"objectName\": \"R(1)'WarmUpGrdnt\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'WarmUpGrdnt\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B5000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 2,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": -5,\r\n" + - " \"maxValue\": 5\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " -5,\r\n" + - " 5\r\n" + - " ],\r\n" + - " \"descr\": \"K\",\r\n" + - " \"descriptionName\": \"Built-in temp. sensor adj.\",\r\n" + - " \"objectName\": \"R(1)'TRBltnMsvAdj\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'TRBltnMsvAdj\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000C6000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 5\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 5\r\n" + - " ],\r\n" + - " \"descr\": \"A\",\r\n" + - " \"descriptionName\": \"Heating device electrical load\",\r\n" + - " \"objectName\": \"R(1)'HDevElLd\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'HDevElLd\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CB000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 5\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 5\r\n" + - " ],\r\n" + - " \"descr\": \"A\",\r\n" + - " \"descriptionName\": \"Q22/Q24 electrical load\",\r\n" + - " \"objectName\": \"R(1)'Q22Q24ElLd\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'Q22Q24ElLd\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 0.5,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CD000055\": {\r\n" + - " \"rep\": 1,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 585.4,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 5000\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 5000\r\n" + - " ],\r\n" + - " \"descr\": \"ppm\",\r\n" + - " \"descriptionName\": \"Room air quality\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'RAQual\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'RAQual\",\r\n" + - " \"translated\": false,\r\n" + - " \"resolution\": 100,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000038000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 13,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Inactive*Active*Null\",\r\n" + - " \"descriptionName\": \"Temporary comfort button\",\r\n" + - " \"objectName\": \"R(1)'ROpModDtr'TmpCmfBtn\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'TmpCmfBtn\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000039000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 13,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Inactive*Active*Null\",\r\n" + - " \"descriptionName\": \"Comfort button\",\r\n" + - " \"objectName\": \"R(1)'ROpModDtr'CmfBtn\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'CmfBtn\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003B000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Absent*Present*Null\",\r\n" + - " \"descriptionName\": \"Room presence detection\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'RPscDet\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'RPscDet\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003F000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 1,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 17,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"No*Yes*Null\",\r\n" + - " \"descriptionName\": \"Enable heating control\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'TCtlH'EnHCtl\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'EnHCtl\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000054000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 0,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Inactive*Active*Null\",\r\n" + - " \"descriptionName\": \"Room presence detector\",\r\n" + - " \"objectName\": \"R(1)'EnRPscDet\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'EnRPscDet\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300004C000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 2,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Off*Protection\",\r\n" + - " \"descriptionName\": \"Off/protection configuration\",\r\n" + - " \"objectName\": \"R(1)'OffPrtCnf\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'OffPrtCnf\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000051000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 2,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 13,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Off*Absent*Present\",\r\n" + - " \"descriptionName\": \"Occupancy mode\",\r\n" + - " \"objectName\": \"R(1)'ROpModDtr'OccMod\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'OccMod\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000052000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 5,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 15,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 5\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Undefined*Poor*Satisfactory*Good*Excellent\",\r\n" + - " \"descriptionName\": \"Energy efficiency indication room\",\r\n" + - " \"objectName\": \"R(1)'RGrnLf'REei\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'REei\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000053000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 1,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 15,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Off*On\",\r\n" + - " \"descriptionName\": \"Domestic hot water mode\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'DhwOp'DhwMod\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwMod\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000056000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 1,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Neither*Heating*Cooling\",\r\n" + - " \"descriptionName\": \"Heating/cooling state\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'HCStaDtr'HCSta\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'HCSta\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300005A000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 2,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"presentPriority\": 13,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 4\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Protection*Unoccupied*Economy*Comfort\",\r\n" + - " \"descriptionName\": \"Present operating mode and reason\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'PrOpModRsn\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'PrOpModRsn\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000071000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 6,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 6\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Default*Slow*Medium*Fast*2-position*Self-adaptive\",\r\n" + - " \"descriptionName\": \"Heating control loop\",\r\n" + - " \"objectName\": \"R(1)'HCtrSet\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'HCtrSet\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000072000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 2,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Warm-up gradient*Self-adaptive\",\r\n" + - " \"descriptionName\": \"Optimum start control setting\",\r\n" + - " \"objectName\": \"R(1)'OsscSet\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'OsscSet\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000074000055\": {\r\n" + - " \"rep\": 3,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": false,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 4,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 4\r\n" + - " ],\r\n" + - " \"descr\": \"Null*Undefined*Poor*Okay*Good\",\r\n" + - " \"descriptionName\": \"Room air quality indication\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'RAQualInd\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'RAQualInd\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000000000055\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 500,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 1,\r\n" + - " \"maxValue\": 8760\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 1,\r\n" + - " 8760\r\n" + - " ],\r\n" + - " \"descr\": \"h\",\r\n" + - " \"descriptionName\": \"Pump/valve kick cycle\",\r\n" + - " \"objectName\": \"R(1)'KickCyc\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'KickCyc\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000001000055\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 180000,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 3600000\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 3600000\r\n" + - " ],\r\n" + - " \"descr\": \"ms\",\r\n" + - " \"descriptionName\": \"DHW min. ON time\",\r\n" + - " \"objectName\": \"R(1)'BoDhwTiOnMin\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOnMin\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000002000055\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 180000,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 3600000\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 3600000\r\n" + - " ],\r\n" + - " \"descr\": \"ms\",\r\n" + - " \"descriptionName\": \"DHW min. OFF time\",\r\n" + - " \"objectName\": \"R(1)'BoDhwTiOffMin\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrAplSet'BoDhwTiOffMin\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000007000055\": {\r\n" + - " \"rep\": 2,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": 604800,\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0,\r\n" + - " \"eventState\": 0,\r\n" + - " \"minValue\": 0,\r\n" + - " \"maxValue\": 4294967295\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 4294967295\r\n" + - " ],\r\n" + - " \"descr\": \"min\",\r\n" + - " \"descriptionName\": \"Operating hours heating\",\r\n" + - " \"objectName\": \"R(1)'RHvacCoo'OphHCDtr'OphH\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'OphH\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000004000055\": {\r\n" + - " \"rep\": 8,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": {\r\n" + - " \"cmd\": \"Command\",\r\n" + - " \"cal\": null,\r\n" + - " \"act\": 0,\r\n" + - " \"null\": 3,\r\n" + - " \"default\": 0,\r\n" + - " \"schedStart\": 4294967295,\r\n" + - " \"schedEnd\": 4294967295,\r\n" + - " \"days\": [\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 3\r\n" + - " ],\r\n" + - " [\r\n" + - " 7687,\r\n" + - " 4\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 3\r\n" + - " ]\r\n" + - " ],\r\n" + - " []\r\n" + - " ],\r\n" + - " \"timeTillNextValue\": 509,\r\n" + - " \"nextValue\": 3\r\n" + - " },\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 4\r\n" + - " ],\r\n" + - " \"descriptionName\": \"Room operating mode scheduler\",\r\n" + - " \"objectName\": \"R(1)'CenOpMod'ROpModSched\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000005000055\": {\r\n" + - " \"rep\": 8,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"value\": {\r\n" + - " \"value\": {\r\n" + - " \"cmd\": \"Command\",\r\n" + - " \"cal\": null,\r\n" + - " \"act\": 0,\r\n" + - " \"null\": 3,\r\n" + - " \"default\": 0,\r\n" + - " \"schedStart\": 4294967295,\r\n" + - " \"schedEnd\": 4294967295,\r\n" + - " \"days\": [\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " [\r\n" + - " [\r\n" + - " 0,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 9,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7689,\r\n" + - " 1\r\n" + - " ],\r\n" + - " [\r\n" + - " 21,\r\n" + - " 2\r\n" + - " ],\r\n" + - " [\r\n" + - " 7701,\r\n" + - " 1\r\n" + - " ]\r\n" + - " ],\r\n" + - " []\r\n" + - " ],\r\n" + - " \"timeTillNextValue\": 479,\r\n" + - " \"nextValue\": 2\r\n" + - " },\r\n" + - " \"statusFlags\": 0,\r\n" + - " \"reliability\": 0\r\n" + - " },\r\n" + - " \"limits\": [\r\n" + - " 0,\r\n" + - " 2\r\n" + - " ],\r\n" + - " \"descriptionName\": \"Domestic hot water scheduler\",\r\n" + - " \"objectName\": \"R(1)'CenDhw'DhwSched\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000400004E\": {\r\n" + - " \"rep\": 9,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"descriptionName\": \"Room operating mode scheduler\",\r\n" + - " \"objectName\": \"R(1)'CenOpMod'ROpModSched\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'ROpModSched\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " },\r\n" + - " \"Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000500004E\": {\r\n" + - " \"rep\": 9,\r\n" + - " \"type\": 0,\r\n" + - " \"write\": true,\r\n" + - " \"webhookEnabled\": false,\r\n" + - " \"descriptionName\": \"Domestic hot water scheduler\",\r\n" + - " \"objectName\": \"R(1)'CenDhw'DhwSched\",\r\n" + - " \"memberName\": \"PresentValue\",\r\n" + - " \"hierarchyName\": \"R(1)'FvrBscOp'DhwSched\",\r\n" + - " \"translated\": false,\r\n" + - " \"isVirtual\": false\r\n" + - " }\r\n" + - " }\r\n" + - "}"; - //@formatter:on - - //@formatter:off - private static final String DATAPOINTS_JSON_REFRESH_SET = - "{\"totalCount\":11," - + "\"values\":{" - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online\":{\"value\":1}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055\":{\"value\":{\"value\":12.6014862,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":-50.0,\"maxValue\":80.0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055\":{\"value\":{\"value\":16.0,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0,\"minValue\":6.0,\"maxValue\":35.0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055\":{\"value\":{\"value\":39.1304474,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":0.0,\"maxValue\":100.0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055\":{\"value\":{\"value\":21.51872,\"statusFlags\":0,\"reliability\":0,\"eventState\":0,\"minValue\":0.0,\"maxValue\":50.0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":13,\"eventState\":0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055\":{\"value\":{\"value\":5,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":15,\"eventState\":0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055\":{\"value\":{\"value\":1,\"statusFlags\":0,\"reliability\":0,\"eventState\":0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055\":{\"value\":{\"value\":2,\"statusFlags\":0,\"reliability\":0,\"presentPriority\":13,\"eventState\":0}}," - + "\"Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055\":{\"value\":{\"value\":4,\"statusFlags\":0,\"reliability\":0,\"eventState\":0}}" - + "}" - + "}"; - //@formatter:on - - //@formatter:off - private static final String PLANTS_JSON = - "{" + - " \"totalCount\": 2," + - " \"items\": [{" + - " \"id\": \"Pd1774247-7de7-4896-ac76-b7e0dd943c40\"," + - " \"activationKey\": \"this-is-not-a-valid-activation-key\"," + - " \"address\": \"\"," + - " \"alarmStatus\": 0," + - " \"applicationSetDescription\": \"Siemens Smart Thermostat\\r\\nRDS110 => Device ID 45\\r\\n\"," + - " \"applicationSetId\": \"9964755b-6766-40bd-ba45-77b2446b71bb\"," + - " \"applicationSetName\": \"STH-Default-RDS110\"," + - " \"asn\": \"RDS110\"," + - " \"assigned\": true," + - " \"city\": \"\"," + - " \"country\": \"\"," + - " \"description\": \"\"," + - " \"energyIndicator\": 0," + - " \"isOnline\": true," + - " \"name\": \"this-is-not-a-valid-activation-key-RDS110\"," + - " \"phone\": \"\"," + - " \"serialNumber\": \"this-is-not-a-valid-activation-key\"," + - " \"state\": \"\"," + - " \"taskStatus\": 0," + - " \"tenant\": \"Siemens STH\"," + - " \"tenantId\": \"T290ea1c1-902c-4c0b-9dce-f96119bc7fc1\"," + - " \"timezone\": \"\"," + - " \"zipCode\": \"\"," + - " \"imsi\": \"\"," + - " \"customerPlantId\": null," + - " \"enhancedPrivileges\": false" + - " }, {" + - " \"id\": \"Pfaf770c8-abeb-4742-ad65-ead39030d369\"," + - " \"activationKey\": \"this-is-not-a-valid-activation-key\"," + - " \"address\": \"\"," + - " \"alarmStatus\": 0," + - " \"applicationSetDescription\": \"Siemens Smart Thermostat\\r\\nRDS110 => Device ID 45\\r\\n\"," + - " \"applicationSetId\": \"9964755b-6766-40bd-ba45-77b2446b71bb\"," + - " \"applicationSetName\": \"STH-Default-RDS110\"," + - " \"asn\": \"RDS110\"," + - " \"assigned\": true," + - " \"city\": \"\"," + - " \"country\": \"\"," + - " \"description\": \"\"," + - " \"energyIndicator\": 0," + - " \"isOnline\": true," + - " \"name\": \"this-is-not-a-valid-activation-key-RDS110\"," + - " \"phone\": \"\"," + - " \"serialNumber\": \"this-is-not-a-valid-activation-key\"," + - " \"state\": \"\"," + - " \"taskStatus\": 0," + - " \"tenant\": \"Siemens STH\"," + - " \"tenantId\": \"T290ea1c1-902c-4c0b-9dce-f96119bc7fc1\"," + - " \"timezone\": \"\"," + - " \"zipCode\": \"\"," + - " \"imsi\": \"\"," + - " \"customerPlantId\": null," + - " \"enhancedPrivileges\": false" + - " }]" + - "}"; - //@formatter:on - - //@formatter:off - private static final String ACCESS_TOKEN_JSON = - "{" + - " \"access_token\": \"this-is-not-a-valid-access_token\"," + - " \"token_type\": \"bearer\"," + - " \"expires_in\": 1209599," + - " \"userName\": \"software@whitebear.ch\"," + - " \".issued\": \"Thu, 06 Jun 2019 10:27:50 GMT\"," + - " \".expires\": \"Thu, 20 Jun 2019 10:27:50 GMT\"" + - "}"; - //@formatter:on + private String load(String fileName) { + try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName)); + BufferedReader reader = new BufferedReader(file)) { + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + return builder.toString(); + } catch (IOException e) { + fail(e.getMessage()); + } + return ""; + } @Test public void test() { @@ -2973,14 +75,13 @@ public void test() { } private void testRdsDataPointsFullNew() { - RdsDataPoints dataPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET_NEW); + RdsDataPoints dataPoints = RdsDataPoints.createFromJson(load("datapoints_full_set_new")); assertNotNull(dataPoints); try { assertEquals("Downstairs", dataPoints.getDescription()); } catch (RdsCloudException e) { fail(e.getMessage()); } - @Nullable Map points = dataPoints.points; assertNotNull(points); @@ -3001,7 +102,7 @@ private void confirmDegreeSymbolCodingNotTrashed() { } private void testRdsDataPointsRefresh() { - RdsDataPoints refreshPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_REFRESH_SET); + RdsDataPoints refreshPoints = RdsDataPoints.createFromJson(load("datapoints_refresh_set")); assertNotNull(refreshPoints); assertNotNull(refreshPoints.points); @@ -3079,7 +180,7 @@ private void testRdsDataPointsRefresh() { assertEquals(state.getClass(), QuantityType.class); assertEquals(4, ((QuantityType) state).intValue()); - RdsDataPoints originalPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET); + RdsDataPoints originalPoints = RdsDataPoints.createFromJson(load("datapoints_full_set")); assertNotNull(originalPoints); assertNotNull(originalPoints.points); @@ -3100,7 +201,7 @@ private void testRdsDataPointsRefresh() { } private void testAccessToken() { - RdsAccessToken accessToken = RdsAccessToken.createFromJson(ACCESS_TOKEN_JSON); + RdsAccessToken accessToken = RdsAccessToken.createFromJson(load("access_token")); assertNotNull(accessToken); try { assertEquals("this-is-not-a-valid-access_token", accessToken.getToken()); @@ -3111,7 +212,7 @@ private void testAccessToken() { } private void testRdsDataPointsFull() { - RdsDataPoints dataPoints = RdsDataPoints.createFromJson(DATAPOINTS_JSON_FULL_SET); + RdsDataPoints dataPoints = RdsDataPoints.createFromJson(load("datapoints_full_set")); assertNotNull(dataPoints); try { assertEquals("Upstairs", dataPoints.getDescription()); @@ -3392,7 +493,7 @@ private void testRdsDataPointsFull() { @SuppressWarnings("null") private void testRdsPlants() { try { - RdsPlants plants = RdsPlants.createFromJson(PLANTS_JSON); + RdsPlants plants = RdsPlants.createFromJson(load("plants")); assertNotNull(plants); List plantList = plants.getPlants(); @@ -3408,7 +509,6 @@ private void testRdsPlants() { assertTrue(plant instanceof PlantInfo); assertEquals("Pfaf770c8-abeb-4742-ad65-ead39030d369", ((PlantInfo) plant).getId()); assertTrue(((PlantInfo) plant).isOnline()); - ; } catch (RdsCloudException e) { fail(e.getMessage()); } diff --git a/bundles/org.openhab.binding.siemensrds/src/test/resources/access_token.json b/bundles/org.openhab.binding.siemensrds/src/test/resources/access_token.json new file mode 100644 index 0000000000000..e9607c8e77a19 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/access_token.json @@ -0,0 +1,8 @@ +{ + "access_token": "this-is-not-a-valid-access_token", + "token_type": "bearer", + "expires_in": 1209599, + "userName": "software@whitebear.ch", + ".issued": "Thu, 06 Jun 2019 10:27:50 GMT", + ".expires": "Thu, 20 Jun 2019 10:27:50 GMT" +} 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 new file mode 100644 index 0000000000000..6df106ccff901 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set.json @@ -0,0 +1,1535 @@ +{ + "totalCount": 67, + "values": { + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00000C": { + "rep": 0, + "type": 0, + "write": false, + "value": "AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;", + "descriptionName": "ApplicationSoftwareVersion", + "objectName": "ApplicationSoftwareVersion", + "memberName": "ApplicationSoftwareVersion", + "hierarchyName": "ApplicationSoftwareVersion", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00001C": { + "rep": 0, + "type": 0, + "write": false, + "value": "Device object", + "descriptionName": "Device Description", + "objectName": "Device Description", + "memberName": "Description", + "hierarchyName": "Device Description", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00002C": { + "rep": 0, + "type": 0, + "write": false, + "value": "FW=02.32.02.27;SVS-300.1:SBC=13.22;I", + "descriptionName": "FirmwareRevision", + "objectName": "FirmwareRevision", + "memberName": "FirmwareRevision", + "hierarchyName": "FirmwareRevision", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000046": { + "rep": 0, + "type": 0, + "write": false, + "value": "RDS110", + "descriptionName": "ModelName", + "objectName": "ModelName", + "memberName": "ModelName", + "hierarchyName": "ModelName", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000070": { + "rep": 3, + "type": 0, + "write": false, + "value": 0, + "limits": [ + 0, + 5 + ], + "descr": "operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress", + "descriptionName": "SystemStatus", + "objectName": "SystemStatus", + "memberName": "SystemStatus", + "hierarchyName": "SystemStatus", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF000077": { + "rep": 2, + "type": 0, + "write": false, + "value": 0, + "descriptionName": "UtcOffset", + "objectName": "UtcOffset", + "memberName": "UtcOffset", + "hierarchyName": "UtcOffset", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF00009B": { + "rep": 2, + "type": 0, + "write": false, + "value": 19, + "descriptionName": "DatabaseRevision", + "objectName": "DatabaseRevision", + "memberName": "DatabaseRevision", + "hierarchyName": "DatabaseRevision", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0000C4": { + "rep": 3, + "type": 0, + "write": false, + "value": 0, + "limits": [ + 0, + 7 + ], + "descr": "unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended", + "descriptionName": "LastRestartReason", + "objectName": "LastRestartReason", + "memberName": "LastRestartReason", + "hierarchyName": "LastRestartReason", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0012DB": { + "rep": 0, + "type": 0, + "write": false, + "value": "MDL:ASN= RDS110;HW=0.2.0;", + "descriptionName": "ModelInformation", + "objectName": "ModelInformation", + "memberName": "4827", + "hierarchyName": "ModelInformation", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF001355": { + "rep": 3, + "type": 0, + "write": false, + "value": 1, + "limits": [ + 0, + 26 + ], + "descr": "-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR", + "descriptionName": "Active SystemLanguge", + "objectName": "Active SystemLanguge", + "memberName": "4949", + "hierarchyName": "Active SystemLanguge", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013B0": { + "rep": 3, + "type": 0, + "write": false, + "value": 26, + "limits": [ + 0, + 72 + ], + "descr": "GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington", + "descriptionName": "TimeZone", + "objectName": "TimeZone", + "memberName": "5040", + "hierarchyName": "TimeZone", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013EC": { + "rep": 0, + "type": 0, + "write": false, + "value": "160100096D", + "descriptionName": "SerialNumber", + "objectName": "SerialNumber", + "memberName": "5100", + "hierarchyName": "SerialNumber", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!0083FFFFF0013F4": { + "rep": 0, + "type": 0, + "write": false, + "value": "'10010'B", + "descriptionName": "Device Features", + "objectName": "Device Features", + "memberName": "5108", + "hierarchyName": "Device Features", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!01D00000700001C": { + "rep": 0, + "type": 0, + "write": true, + "value": "Upstairs", + "descriptionName": "R(1)'Description", + "objectName": "R(1)'Description", + "memberName": "Description", + "hierarchyName": "R(1)'Description", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130B": { + "rep": 0, + "type": 0, + "write": false, + "value": "192.168.1.1", + "descriptionName": "NwkPortIP'IP gefault gateway", + "objectName": "NwkPortIP'IP gefault gateway", + "memberName": "4875", + "hierarchyName": "NwkPortIP'IP gefault gateway", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130C": { + "rep": 0, + "type": 0, + "write": false, + "value": "255.255.255.0", + "descriptionName": "NwkPortIP'IP subnet mask", + "objectName": "NwkPortIP'IP subnet mask", + "memberName": "4876", + "hierarchyName": "NwkPortIP'IP subnet mask", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130D": { + "rep": 0, + "type": 0, + "write": false, + "value": "192.168.1.42", + "descriptionName": "NwkPortIP'IP address", + "objectName": "NwkPortIP'IP address", + "memberName": "4877", + "hierarchyName": "NwkPortIP'IP address", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!10800000000130E": { + "rep": 2, + "type": 0, + "write": false, + "value": 47808, + "descriptionName": "NwkPortIP'UDP Port", + "objectName": "NwkPortIP'UDP Port", + "memberName": "4878", + "hierarchyName": "NwkPortIP'UDP Port", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000000001313": { + "rep": 0, + "type": 0, + "write": false, + "value": "'F0C77F6C1895'H", + "descriptionName": "NwkPortIP'BACnet MAC address", + "objectName": "NwkPortIP'BACnet MAC address", + "memberName": "4883", + "hierarchyName": "NwkPortIP'BACnet MAC address", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001286": { + "rep": 0, + "type": 0, + "write": false, + "value": "sth.connectivity.ccl-siemens.com", + "descriptionName": "NwkPortCCL'Connection URI", + "objectName": "NwkPortCCL'Connection URI", + "memberName": "4742", + "hierarchyName": "NwkPortCCL'Connection URI", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001287": { + "rep": 0, + "type": 0, + "write": false, + "value": "this-is-not-a-valid-activation-key", + "descriptionName": "NwkPortCCL'Activation Key", + "objectName": "NwkPortCCL'Activation Key", + "memberName": "4743", + "hierarchyName": "NwkPortCCL'Activation Key", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!108000001001288": { + "rep": 2, + "type": 0, + "write": false, + "value": 60, + "descriptionName": "NwkPortCCL'Reconection delay", + "objectName": "NwkPortCCL'Reconection delay", + "memberName": "4744", + "hierarchyName": "NwkPortCCL'Reconection delay", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdPerMin": { + "rep": 2, + "type": 0, + "write": false, + "value": 0, + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Item Updates per Minute", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!DPUpdTotal": { + "rep": 2, + "type": 0, + "write": false, + "value": 286849, + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Item Updates Total", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Languages": { + "rep": 0, + "type": 0, + "write": false, + "value": "-;en", + "limits": [ + 0, + 1 + ], + "objectName": "CSL-Config", + "memberName": "Languages", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online": { + "rep": 3, + "type": 0, + "write": false, + "value": 1, + "limits": [ + 0, + 1 + ], + "descr": "Offline*Online", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Online", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInPerMin": { + "rep": 2, + "type": 0, + "write": false, + "value": 1473, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Inbound per Minute", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcInTotal": { + "rep": 2, + "type": 0, + "write": false, + "value": 178130801, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Inbound Total", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutPerMin": { + "rep": 2, + "type": 0, + "write": false, + "value": 616, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Outbound per Minute", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!TrfcOutTotal": { + "rep": 2, + "type": 0, + "write": false, + "value": 60624666, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Outbound Total", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055": { + "rep": 1, + "type": 0, + "write": false, + "value": { + "value": 18.5519028, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": -50, + "maxValue": 80 + }, + "limits": [ + -50, + 80 + ], + "descr": "°C", + "descriptionName": "Outside air temperature", + "objectName": "R(1)'TOa", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'TOa", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000002000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5 + }, + "limits": [ + 0, + 5 + ], + "descr": "A", + "descriptionName": "Heating device electrical load", + "objectName": "R(1)'HDevElLd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'HDevElLd", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00200007F000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 24, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 17, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°C", + "descriptionName": "Comfort heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHCmf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHCmf", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000080000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 24, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°F", + "descriptionName": "Pre-comfort heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHPcf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHPcf", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000081000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 16, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°C", + "descriptionName": "Economy heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHEco", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHEco", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000082000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 6, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°C", + "descriptionName": "Protection heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHPrt", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'SpHPrt", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 24, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0, + "minValue": 6, + "maxValue": 35 + }, + "limits": [ + 12, + 35 + ], + "descr": "°C", + "descriptionName": "Room temperature setpoint", + "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTR", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpTR", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000084000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0, + "minValue": -18, + "maxValue": 11 + }, + "limits": [ + -9, + 14 + ], + "descr": "K", + "descriptionName": "Room temperature setpoint shift", + "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTRShft", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpTRShft", + "translated": false, + "resolution": 0.10000000149011612 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055": { + "rep": 1, + "type": 0, + "write": false, + "value": { + "value": 46.86865, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 100 + }, + "limits": [ + 0, + 100 + ], + "descr": "%r.H.", + "descriptionName": "Relative humidity for room", + "objectName": "R(1)'RHvacCoo'RHuRel", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RHuRel", + "translated": false, + "resolution": 1 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055": { + "rep": 1, + "type": 0, + "write": false, + "value": { + "value": 23.761879, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°C", + "descriptionName": "Room temperature", + "objectName": "R(1)'RHvacCoo'RTemp", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RTemp", + "translated": false, + "resolution": 0.10000000149011612 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B2000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 35, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "°C", + "descriptionName": "Max. heating setpoint", + "objectName": "R(1)'SpTRMaxHCmf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'SpTRMaxHCmf", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B4000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 30, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 120 + }, + "limits": [ + 0, + 120 + ], + "descr": "Unknown Unit(236)", + "descriptionName": "Warm-up gradient", + "objectName": "R(1)'WarmUpGrdnt", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'WarmUpGrdnt", + "translated": false, + "resolution": 5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000B5000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": -5, + "maxValue": 5 + }, + "limits": [ + -5, + 5 + ], + "descr": "K", + "descriptionName": "Built-in temp. sensor adj.", + "objectName": "R(1)'TRBltnMsvAdj", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'TRBltnMsvAdj", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CB000055": { + "rep": 1, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5 + }, + "limits": [ + 0, + 5 + ], + "descr": "A", + "descriptionName": "Q22/Q24 electrical load", + "objectName": "R(1)'Q22Q24ElLd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'Q22Q24ElLd", + "translated": false, + "resolution": 0.5 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!0020000CD000055": { + "rep": 1, + "type": 0, + "write": false, + "value": { + "value": 713, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5000 + }, + "limits": [ + 0, + 5000 + ], + "descr": "ppm", + "descriptionName": "Room air quality", + "objectName": "R(1)'RHvacCoo'RAQual", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RAQual", + "translated": false, + "resolution": 100 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000038000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Temporary comfort button", + "objectName": "R(1)'ROpModDtr'TmpCmfBtn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'TmpCmfBtn", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000039000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Comfort button", + "objectName": "R(1)'ROpModDtr'CmfBtn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'CmfBtn", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003B000055": { + "rep": 3, + "type": 0, + "write": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Absent*Present*Null", + "descriptionName": "Room presence detection", + "objectName": "R(1)'RHvacCoo'RPscDet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RPscDet", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00500003F000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 17, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "No*Yes*Null", + "descriptionName": "Enable heating control", + "objectName": "R(1)'RHvacCoo'TCtlH'EnHCtl", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'EnHCtl", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!005000054000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Room presence detector", + "objectName": "R(1)'EnRPscDet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'EnRPscDet", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300004C000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Off*Protection", + "descriptionName": "Off/protection configuration", + "objectName": "R(1)'OffPrtCnf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'OffPrtCnf", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 3, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 3 + ], + "descr": "Null*Off*Absent*Present", + "descriptionName": "Occupancy mode", + "objectName": "R(1)'ROpModDtr'OccMod", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'OccMod", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 5, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + }, + "limits": [ + 0, + 5 + ], + "descr": "Null*Undefined*Poor*Satisfactory*Good*Excellent", + "descriptionName": "Energy efficiency indication room", + "objectName": "R(1)'RGrnLf'REei", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'REei", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Off*On", + "descriptionName": "Domestic hot water mode", + "objectName": "R(1)'RHvacCoo'DhwOp'DhwMod", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwMod", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055": { + "rep": 3, + "type": 0, + "write": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 3 + ], + "descr": "Null*Neither*Heating*Cooling", + "descriptionName": "Heating/cooling state", + "objectName": "R(1)'RHvacCoo'HCStaDtr'HCSta", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'HCSta", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 4, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + }, + "limits": [ + 0, + 4 + ], + "descr": "Null*Protection*Economy*Pre-Comfort*Comfort", + "descriptionName": "Present operating mode and reason", + "objectName": "R(1)'RHvacCoo'PrOpModRsn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'PrOpModRsn", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000071000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 6, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 6 + ], + "descr": "Null*Default*Slow*Medium*Fast*2-position*Self-adaptive", + "descriptionName": "Heating control loop", + "objectName": "R(1)'HCtrSet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'HCtrSet", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000072000055": { + "rep": 3, + "type": 0, + "write": true, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Warm-up gradient*Self-adaptive", + "descriptionName": "Optimum start control setting", + "objectName": "R(1)'OsscSet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'OsscSet", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055": { + "rep": 3, + "type": 0, + "write": false, + "value": { + "value": 4, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 4 + ], + "descr": "Null*Undefined*Poor*Okay*Good", + "descriptionName": "Room air quality indication", + "objectName": "R(1)'RHvacCoo'RAQualInd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RAQualInd", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000000000055": { + "rep": 2, + "type": 0, + "write": true, + "value": { + "value": 500, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 1, + "maxValue": 8760 + }, + "limits": [ + 1, + 8760 + ], + "descr": "h", + "descriptionName": "Pump/valve kick cycle", + "objectName": "R(1)'KickCyc", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'KickCyc", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000001000055": { + "rep": 2, + "type": 0, + "write": true, + "value": { + "value": 180000, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 3600000 + }, + "limits": [ + 0, + 3600000 + ], + "descr": "ms", + "descriptionName": "DHW min. ON time", + "objectName": "R(1)'BoDhwTiOnMin", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'BoDhwTiOnMin", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000002000055": { + "rep": 2, + "type": 0, + "write": true, + "value": { + "value": 180000, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 3600000 + }, + "limits": [ + 0, + 3600000 + ], + "descr": "ms", + "descriptionName": "DHW min. OFF time", + "objectName": "R(1)'BoDhwTiOffMin", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'BoDhwTiOffMin", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!030000007000055": { + "rep": 2, + "type": 0, + "write": true, + "value": { + "value": 253140, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 4294967295 + }, + "limits": [ + 0, + 4294967295 + ], + "descr": "min", + "descriptionName": "Operating hours heating", + "objectName": "R(1)'RHvacCoo'OphHCDtr'OphH", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'OphH", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000004000055": { + "rep": 8, + "type": 0, + "write": true, + "value": { + "value": { + "cmd": "Command", + "cal": null, + "act": 0, + "null": 3, + "default": 0, + "schedStart": 4294967295, + "schedEnd": 4294967295, + "days": [ + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + ] + ], + "timeTillNextValue": 632, + "nextValue": 3 + }, + "statusFlags": 0, + "reliability": 0 + }, + "limits": [ + 0, + 4 + ], + "descriptionName": "Room operating mode scheduler", + "objectName": "R(1)'CenOpMod'ROpModSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'ROpModSched", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;2!011000005000055": { + "rep": 8, + "type": 0, + "write": true, + "value": { + "value": { + "cmd": "Command", + "cal": null, + "act": 0, + "null": 3, + "default": 0, + "schedStart": 4294967295, + "schedEnd": 4294967295, + "days": [ + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 8, + 2 + ], + [ + 11543, + 1 + ] + ], + [ + ] + ], + "timeTillNextValue": 767, + "nextValue": 1 + }, + "statusFlags": 0, + "reliability": 0 + }, + "limits": [ + 0, + 2 + ], + "descriptionName": "Domestic hot water scheduler", + "objectName": "R(1)'CenDhw'DhwSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwSched", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000400004E": { + "rep": 9, + "type": 0, + "write": true, + "value": { + "value": { + "act": 0, + "rules": [ + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ] + ] + }, + "statusFlags": 0, + "reliability": 0 + }, + "descriptionName": "Room operating mode scheduler", + "objectName": "R(1)'CenOpMod'ROpModSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'ROpModSched", + "translated": false + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;3!01100000500004E": { + "rep": 9, + "type": 0, + "write": true, + "value": { + "value": { + "act": 0, + "rules": [ + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ], + [ + 3, + 4294967295, + 4294967295, + 4294967295 + ] + ] + }, + "statusFlags": 0, + "reliability": 0 + }, + "descriptionName": "Domestic hot water scheduler", + "objectName": "R(1)'CenDhw'DhwSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwSched", + "translated": false + } + } +} 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 new file mode 100644 index 0000000000000..89b4c92cbb725 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_full_set_new.json @@ -0,0 +1,1625 @@ +{ + "totalCount": 70, + "values": { + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00000C": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "AAS-20:SU=SiUn;APT=HvacFnct18z_A;APTV=2.003;APS=1;", + "descriptionName": "ApplicationSoftwareVersion", + "objectName": "ApplicationSoftwareVersion", + "memberName": "ApplicationSoftwareVersion", + "hierarchyName": "ApplicationSoftwareVersion", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00001C": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "Device object", + "descriptionName": "Device Description", + "objectName": "Device Description", + "memberName": "Description", + "hierarchyName": "Device Description", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00002C": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "FW=02.32.02.27;SVS-300.1:SBC=13.22;I", + "descriptionName": "FirmwareRevision", + "objectName": "FirmwareRevision", + "memberName": "FirmwareRevision", + "hierarchyName": "FirmwareRevision", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000046": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "RDS110", + "descriptionName": "ModelName", + "objectName": "ModelName", + "memberName": "ModelName", + "hierarchyName": "ModelName", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000070": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 0, + "limits": [ + 0, + 5 + ], + "descr": "operational*operational-read-only*download-required*download-in-progress*non-operational*backup-in-progress", + "descriptionName": "SystemStatus", + "objectName": "SystemStatus", + "memberName": "SystemStatus", + "hierarchyName": "SystemStatus", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF000077": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 0, + "descriptionName": "UtcOffset", + "objectName": "UtcOffset", + "memberName": "UtcOffset", + "hierarchyName": "UtcOffset", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF00009B": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 29, + "descriptionName": "DatabaseRevision", + "objectName": "DatabaseRevision", + "memberName": "DatabaseRevision", + "hierarchyName": "DatabaseRevision", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0000C4": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 4, + "limits": [ + 0, + 7 + ], + "descr": "unknown*coldstart*warmstart*detected-power-lost*detected-powered-off*hardware-watchdog*software-watchdog*suspended", + "descriptionName": "LastRestartReason", + "objectName": "LastRestartReason", + "memberName": "LastRestartReason", + "hierarchyName": "LastRestartReason", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0012DB": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "MDL:ASN= RDS110;HW=0.2.0;", + "descriptionName": "ModelInformation", + "objectName": "ModelInformation", + "memberName": "4827", + "hierarchyName": "ModelInformation", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF001355": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 1, + "limits": [ + 0, + 26 + ], + "descr": "-*en*de*fr*es*cs*da*nl*fi*it*hu*nb*pl*pt*ru*sk*sv*zh*zh*ko*ro*tr*en-US*fr-CA*es-mx*pt-BR", + "descriptionName": "Active SystemLanguge", + "objectName": "Active SystemLanguge", + "memberName": "4949", + "hierarchyName": "Active SystemLanguge", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013B0": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 26, + "limits": [ + 0, + 72 + ], + "descr": "GMT-12:00 Kwajalein*GMT-11:00 Samoa, Midway*GMT-10:00 Hawaii*GMT-09:00 Alaska*GMT-08:00 Pacific Time*GMT-07:00 Arizona*GMT-07:00 Chihuahua*GMT-07:00 Mountain Time*GMT-06:00 Central America*GMT-06:00 Central Time*GMT-06:00 Mexico City*GMT-06:00 Saskatchewan*GMT-05:00 Bogota, Lima*GMT-05:00 Eastern Time*GMT-05:00 Indiana (USA)*GMT-04:00 Atlantic Time*GMT-04:00 Caracas, La Paz*GMT-04:00 Santiago*18*GMT-03:00 Brasilia*20*21*GMT-02:00 Mid-Atlantic*23*24*25*GMT London, Dublin, Lisbon*GMT+01:00 Berlin, Rome*GMT+01:00 Budapest, Prague*GMT+01:00 Paris, Madrid*GMT+01:00 Vienna, Warsaw*31*GMT+02:00 Athens, Istanbul*GMT+02:00 Bucharest*GMT+02:00 Cairo*GMT+02:00 Johannesburg, Harare*GMT+02:00 Helsinki, Riga*GMT+02:00 Jerusalem*38*GMT+03:00 Kuwait, Riyadh*GMT+04:00 Moscow*41*GMT+03:30 Tehran*GMT+04:00 Abu Dhabi, Muscat*GMT+04:00 Baku, Tbilisi*45*GMT+06:00 Ekaterinburg*47*GMT+05:30 New Delhi*49*GMT+07:00 Omsk, Novosibirsk *51*52*53*GMT+07:00 Bangkok, Jakarta*GMT+08:00 Krasnoyarsk*GMT+08:00 Beijing, Hong Kong*GMT+09:00 Irkutsk*GMT+08:00 Kuala Lumpur*GMT+08:00 Perth*GMT+08:00 Taipei*GMT+09:00 Tokyo, Osaka*GMT+09:00 Seoul*GMT+10:00 Yakutsk*GMT+09:30 Adelaide*GMT+09:30 Darwin*GMT+10:00 Brisbane*GMT+10:00 Melbourne, Sydney*68*69*GMT+11:00 Vladivostok*71*GMT+12:00 Auckland, Wellington", + "descriptionName": "TimeZone", + "objectName": "TimeZone", + "memberName": "5040", + "hierarchyName": "TimeZone", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013EC": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "160100078A", + "descriptionName": "SerialNumber", + "objectName": "SerialNumber", + "memberName": "5100", + "hierarchyName": "SerialNumber", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!0083FFFFF0013F4": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "'10010'B", + "descriptionName": "Device Features", + "objectName": "Device Features", + "memberName": "5108", + "hierarchyName": "Device Features", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!01D00000700001C": { + "rep": 0, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": "Downstairs", + "descriptionName": "R(1)'Description", + "objectName": "R(1)'Description", + "memberName": "Description", + "hierarchyName": "R(1)'Description", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130B": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "192.168.1.1", + "descriptionName": "NwkPortIP'IP gefault gateway", + "objectName": "NwkPortIP'IP gefault gateway", + "memberName": "4875", + "hierarchyName": "NwkPortIP'IP gefault gateway", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130C": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "255.255.255.0", + "descriptionName": "NwkPortIP'IP subnet mask", + "objectName": "NwkPortIP'IP subnet mask", + "memberName": "4876", + "hierarchyName": "NwkPortIP'IP subnet mask", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130D": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "192.168.1.41", + "descriptionName": "NwkPortIP'IP address", + "objectName": "NwkPortIP'IP address", + "memberName": "4877", + "hierarchyName": "NwkPortIP'IP address", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!10800000000130E": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 47808, + "descriptionName": "NwkPortIP'UDP Port", + "objectName": "NwkPortIP'UDP Port", + "memberName": "4878", + "hierarchyName": "NwkPortIP'UDP Port", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000000001313": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "'F0C77F6C10A1'H", + "descriptionName": "NwkPortIP'BACnet MAC address", + "objectName": "NwkPortIP'BACnet MAC address", + "memberName": "4883", + "hierarchyName": "NwkPortIP'BACnet MAC address", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001286": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "sth.connectivity.ccl-siemens.com", + "descriptionName": "NwkPortCCL'Connection URI", + "objectName": "NwkPortCCL'Connection URI", + "memberName": "4742", + "hierarchyName": "NwkPortCCL'Connection URI", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001287": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "HABEAS-XXQFD-JRHUP-YNAFG-FNE4Q", + "descriptionName": "NwkPortCCL'Activation Key", + "objectName": "NwkPortCCL'Activation Key", + "memberName": "4743", + "hierarchyName": "NwkPortCCL'Activation Key", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!108000001001288": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 60, + "descriptionName": "NwkPortCCL'Reconection delay", + "objectName": "NwkPortCCL'Reconection delay", + "memberName": "4744", + "hierarchyName": "NwkPortCCL'Reconection delay", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdCurMon": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 3685, + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Item Updates Current Month", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdPerMin": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 1, + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Item Updates per Minute", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!DPUpdTotal": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 429857, + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Item Updates Total", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Languages": { + "rep": 0, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": "-;en", + "limits": [ + 0, + 1 + ], + "objectName": "CSL-Config", + "memberName": "Languages", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!Online": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 1, + "limits": [ + 0, + 1 + ], + "descr": "Offline*Online", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Online", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInCurMon": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 6836970, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Inbound Current Month", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInPerMin": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 183, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Inbound per Minute", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcInTotal": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 361410891, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Inbound Total", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutCurMon": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 1641440, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Outbound Current Month", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutPerMin": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 62, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Outbound per Minute", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;0!TrfcOutTotal": { + "rep": 2, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": 105878276, + "descr": "bytes", + "descriptionName": "Target", + "objectName": "Target", + "memberName": "Traffic Outbound Total", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00000000E000055": { + "rep": 1, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 21.4816036, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": -50, + "maxValue": 80 + }, + "limits": [ + -50, + 80 + ], + "descr": "�C", + "descriptionName": "Outside air temperature", + "objectName": "R(1)'TOa", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'TOa", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00200007F000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 24, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 17, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Comfort heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHCmf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHCmf", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000080000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 24, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Economy heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHPcf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHPcf", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000081000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 16, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Unoccupied heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHEco", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpHEco", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000082000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 6, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Protection heating setpoint", + "objectName": "R(1)'RHvacCoo'TCtlH'SpHPrt", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'SpHPrt", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000083000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 16, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0, + "minValue": 6, + "maxValue": 35 + }, + "limits": [ + 6, + 35 + ], + "descr": "�C", + "descriptionName": "Room temperature setpoint", + "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTR", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpTR", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000084000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0, + "minValue": -10, + "maxValue": 19 + }, + "limits": [ + -18, + 11 + ], + "descr": "K", + "descriptionName": "Room temperature setpoint shift", + "objectName": "R(1)'RHvacCoo'SpTRDtr'SpTRShft", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'SpTRShft", + "translated": false, + "resolution": 0.10000000149011612, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000085000055": { + "rep": 1, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 36.1050224, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 100 + }, + "limits": [ + 0, + 100 + ], + "descr": "%r.H.", + "descriptionName": "Relative humidity for room", + "objectName": "R(1)'RHvacCoo'RHuRel", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RHuRel", + "translated": false, + "resolution": 1, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!002000086000055": { + "rep": 1, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 24.2482586, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Room temperature", + "objectName": "R(1)'RHvacCoo'RTemp", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RTemp", + "translated": false, + "resolution": 0.10000000149011612, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B2000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 35, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + }, + "limits": [ + 0, + 50 + ], + "descr": "�C", + "descriptionName": "Max. heating setpoint", + "objectName": "R(1)'SpTRMaxHCmf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'SpTRMaxHCmf", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B4000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 30, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 120 + }, + "limits": [ + 0, + 120 + ], + "descr": "Unknown Unit(236)", + "descriptionName": "Warm-up gradient", + "objectName": "R(1)'WarmUpGrdnt", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'WarmUpGrdnt", + "translated": false, + "resolution": 5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000B5000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": -5, + "maxValue": 5 + }, + "limits": [ + -5, + 5 + ], + "descr": "K", + "descriptionName": "Built-in temp. sensor adj.", + "objectName": "R(1)'TRBltnMsvAdj", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'TRBltnMsvAdj", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000C6000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5 + }, + "limits": [ + 0, + 5 + ], + "descr": "A", + "descriptionName": "Heating device electrical load", + "objectName": "R(1)'HDevElLd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'HDevElLd", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CB000055": { + "rep": 1, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5 + }, + "limits": [ + 0, + 5 + ], + "descr": "A", + "descriptionName": "Q22/Q24 electrical load", + "objectName": "R(1)'Q22Q24ElLd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'Q22Q24ElLd", + "translated": false, + "resolution": 0.5, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!0020000CD000055": { + "rep": 1, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 585.4, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 5000 + }, + "limits": [ + 0, + 5000 + ], + "descr": "ppm", + "descriptionName": "Room air quality", + "objectName": "R(1)'RHvacCoo'RAQual", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RAQual", + "translated": false, + "resolution": 100, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000038000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Temporary comfort button", + "objectName": "R(1)'ROpModDtr'TmpCmfBtn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'TmpCmfBtn", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000039000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Comfort button", + "objectName": "R(1)'ROpModDtr'CmfBtn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'CmfBtn", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003B000055": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Absent*Present*Null", + "descriptionName": "Room presence detection", + "objectName": "R(1)'RHvacCoo'RPscDet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RPscDet", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!00500003F000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 17, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "No*Yes*Null", + "descriptionName": "Enable heating control", + "objectName": "R(1)'RHvacCoo'TCtlH'EnHCtl", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'EnHCtl", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!005000054000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 0, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Inactive*Active*Null", + "descriptionName": "Room presence detector", + "objectName": "R(1)'EnRPscDet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'EnRPscDet", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300004C000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Off*Protection", + "descriptionName": "Off/protection configuration", + "objectName": "R(1)'OffPrtCnf", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'OffPrtCnf", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000051000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 3 + ], + "descr": "Null*Off*Absent*Present", + "descriptionName": "Occupancy mode", + "objectName": "R(1)'ROpModDtr'OccMod", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'OccMod", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000052000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 5, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + }, + "limits": [ + 0, + 5 + ], + "descr": "Null*Undefined*Poor*Satisfactory*Good*Excellent", + "descriptionName": "Energy efficiency indication room", + "objectName": "R(1)'RGrnLf'REei", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'REei", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000053000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Off*On", + "descriptionName": "Domestic hot water mode", + "objectName": "R(1)'RHvacCoo'DhwOp'DhwMod", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwMod", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000056000055": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 3 + ], + "descr": "Null*Neither*Heating*Cooling", + "descriptionName": "Heating/cooling state", + "objectName": "R(1)'RHvacCoo'HCStaDtr'HCSta", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'HCSta", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!01300005A000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + }, + "limits": [ + 0, + 4 + ], + "descr": "Null*Protection*Unoccupied*Economy*Comfort", + "descriptionName": "Present operating mode and reason", + "objectName": "R(1)'RHvacCoo'PrOpModRsn", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'PrOpModRsn", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000071000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 6, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 6 + ], + "descr": "Null*Default*Slow*Medium*Fast*2-position*Self-adaptive", + "descriptionName": "Heating control loop", + "objectName": "R(1)'HCtrSet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'HCtrSet", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000072000055": { + "rep": 3, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 2 + ], + "descr": "Null*Warm-up gradient*Self-adaptive", + "descriptionName": "Optimum start control setting", + "objectName": "R(1)'OsscSet", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'OsscSet", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!013000074000055": { + "rep": 3, + "type": 0, + "write": false, + "webhookEnabled": false, + "value": { + "value": 4, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + }, + "limits": [ + 0, + 4 + ], + "descr": "Null*Undefined*Poor*Okay*Good", + "descriptionName": "Room air quality indication", + "objectName": "R(1)'RHvacCoo'RAQualInd", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'RAQualInd", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000000000055": { + "rep": 2, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 500, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 1, + "maxValue": 8760 + }, + "limits": [ + 1, + 8760 + ], + "descr": "h", + "descriptionName": "Pump/valve kick cycle", + "objectName": "R(1)'KickCyc", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'KickCyc", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000001000055": { + "rep": 2, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 180000, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 3600000 + }, + "limits": [ + 0, + 3600000 + ], + "descr": "ms", + "descriptionName": "DHW min. ON time", + "objectName": "R(1)'BoDhwTiOnMin", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'BoDhwTiOnMin", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000002000055": { + "rep": 2, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 180000, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 3600000 + }, + "limits": [ + 0, + 3600000 + ], + "descr": "ms", + "descriptionName": "DHW min. OFF time", + "objectName": "R(1)'BoDhwTiOffMin", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrAplSet'BoDhwTiOffMin", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;1!030000007000055": { + "rep": 2, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": 604800, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 4294967295 + }, + "limits": [ + 0, + 4294967295 + ], + "descr": "min", + "descriptionName": "Operating hours heating", + "objectName": "R(1)'RHvacCoo'OphHCDtr'OphH", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'OphH", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000004000055": { + "rep": 8, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": { + "cmd": "Command", + "cal": null, + "act": 0, + "null": 3, + "default": 0, + "schedStart": 4294967295, + "schedEnd": 4294967295, + "days": [ + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + [ + 0, + 3 + ], + [ + 7687, + 4 + ], + [ + 7701, + 3 + ] + ], + [ + ] + ], + "timeTillNextValue": 509, + "nextValue": 3 + }, + "statusFlags": 0, + "reliability": 0 + }, + "limits": [ + 0, + 4 + ], + "descriptionName": "Room operating mode scheduler", + "objectName": "R(1)'CenOpMod'ROpModSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'ROpModSched", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;2!011000005000055": { + "rep": 8, + "type": 0, + "write": true, + "webhookEnabled": false, + "value": { + "value": { + "cmd": "Command", + "cal": null, + "act": 0, + "null": 3, + "default": 0, + "schedStart": 4294967295, + "schedEnd": 4294967295, + "days": [ + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + [ + 0, + 1 + ], + [ + 9, + 2 + ], + [ + 7689, + 1 + ], + [ + 21, + 2 + ], + [ + 7701, + 1 + ] + ], + [ + ] + ], + "timeTillNextValue": 479, + "nextValue": 2 + }, + "statusFlags": 0, + "reliability": 0 + }, + "limits": [ + 0, + 2 + ], + "descriptionName": "Domestic hot water scheduler", + "objectName": "R(1)'CenDhw'DhwSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwSched", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000400004E": { + "rep": 9, + "type": 0, + "write": true, + "webhookEnabled": false, + "descriptionName": "Room operating mode scheduler", + "objectName": "R(1)'CenOpMod'ROpModSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'ROpModSched", + "translated": false, + "isVirtual": false + }, + "Pfaf770c8-abeb-4742-ad65-ead39030d369;3!01100000500004E": { + "rep": 9, + "type": 0, + "write": true, + "webhookEnabled": false, + "descriptionName": "Domestic hot water scheduler", + "objectName": "R(1)'CenDhw'DhwSched", + "memberName": "PresentValue", + "hierarchyName": "R(1)'FvrBscOp'DhwSched", + "translated": false, + "isVirtual": false + } + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_refresh_set.json b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_refresh_set.json new file mode 100644 index 0000000000000..06af2d9dfd209 --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/datapoints_refresh_set.json @@ -0,0 +1,101 @@ +{ + "totalCount": 11, + "values": { + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;0!Online": { + "value": 1 + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!00000000E000055": { + "value": { + "value": 12.6014862, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": -50, + "maxValue": 80 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000083000055": { + "value": { + "value": 16, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0, + "minValue": 6, + "maxValue": 35 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000085000055": { + "value": { + "value": 39.1304474, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 100 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!002000086000055": { + "value": { + "value": 21.51872, + "statusFlags": 0, + "reliability": 0, + "eventState": 0, + "minValue": 0, + "maxValue": 50 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000051000055": { + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000052000055": { + "value": { + "value": 5, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000053000055": { + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 15, + "eventState": 0 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000056000055": { + "value": { + "value": 1, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!01300005A000055": { + "value": { + "value": 2, + "statusFlags": 0, + "reliability": 0, + "presentPriority": 13, + "eventState": 0 + } + }, + "Pd1774247-7de7-4896-ac76-b7e0dd943c40;1!013000074000055": { + "value": { + "value": 4, + "statusFlags": 0, + "reliability": 0, + "eventState": 0 + } + } + } +} diff --git a/bundles/org.openhab.binding.siemensrds/src/test/resources/plants.json b/bundles/org.openhab.binding.siemensrds/src/test/resources/plants.json new file mode 100644 index 0000000000000..4558cc02faefa --- /dev/null +++ b/bundles/org.openhab.binding.siemensrds/src/test/resources/plants.json @@ -0,0 +1,61 @@ +{ + "totalCount": 2, + "items": [ + { + "id": "Pd1774247-7de7-4896-ac76-b7e0dd943c40", + "activationKey": "this-is-not-a-valid-activation-key", + "address": "", + "alarmStatus": 0, + "applicationSetDescription": "Siemens Smart Thermostat\r\nRDS110 => Device ID 45\r\n", + "applicationSetId": "9964755b-6766-40bd-ba45-77b2446b71bb", + "applicationSetName": "STH-Default-RDS110", + "asn": "RDS110", + "assigned": true, + "city": "", + "country": "", + "description": "", + "energyIndicator": 0, + "isOnline": true, + "name": "this-is-not-a-valid-activation-key-RDS110", + "phone": "", + "serialNumber": "this-is-not-a-valid-activation-key", + "state": "", + "taskStatus": 0, + "tenant": "Siemens STH", + "tenantId": "T290ea1c1-902c-4c0b-9dce-f96119bc7fc1", + "timezone": "", + "zipCode": "", + "imsi": "", + "customerPlantId": null, + "enhancedPrivileges": false + }, + { + "id": "Pfaf770c8-abeb-4742-ad65-ead39030d369", + "activationKey": "this-is-not-a-valid-activation-key", + "address": "", + "alarmStatus": 0, + "applicationSetDescription": "Siemens Smart Thermostat\r\nRDS110 => Device ID 45\r\n", + "applicationSetId": "9964755b-6766-40bd-ba45-77b2446b71bb", + "applicationSetName": "STH-Default-RDS110", + "asn": "RDS110", + "assigned": true, + "city": "", + "country": "", + "description": "", + "energyIndicator": 0, + "isOnline": true, + "name": "this-is-not-a-valid-activation-key-RDS110", + "phone": "", + "serialNumber": "this-is-not-a-valid-activation-key", + "state": "", + "taskStatus": 0, + "tenant": "Siemens STH", + "tenantId": "T290ea1c1-902c-4c0b-9dce-f96119bc7fc1", + "timezone": "", + "zipCode": "", + "imsi": "", + "customerPlantId": null, + "enhancedPrivileges": false + } + ] +} From 27eed7c9c257a9f963e447538ef794852722a2a7 Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Tue, 26 May 2020 10:15:38 +0100 Subject: [PATCH 3/4] [siemensrds] adopted code review suggestions by @cpmeister Signed-off-by: Andrew Fiddian-Green --- .../siemensrds/internal/RdsDataPoints.java | 69 ++++++++----------- .../siemensrds/points/PointDeserializer.java | 24 +++---- .../binding/siemensrds/test/RdsTestData.java | 49 +++++++------ 3 files changed, 62 insertions(+), 80 deletions(-) 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 5543dfa1de32b..9c9e03040955f 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 @@ -64,18 +64,18 @@ public class RdsDataPoints { private static final Gson GSON = new GsonBuilder().registerTypeAdapter(BasePoint.class, new PointDeserializer()) .create(); + /* + * this is a second index into to the JSON "values" points Map below; the + * purpose is to allow point lookups by a) pointId (which we do directly from + * the Map, and b) by pointClass (which we do indirectly "double dereferenced" + * via this index + */ + private final Map indexClassToId = new HashMap<>(); + @SerializedName("totalCount") private @Nullable String totalCount; @SerializedName("values") - public @Nullable Map points; - - /* - * this is a second index into to the points Map above; the purpose is to allow - * point lookups by a) pointId (which we do directly from the Map, and b) by - * pointClass (which we do indirectly "double dereferenced" via this second - * index - */ - private Map indexClassToId = new HashMap<>(); + public @Nullable Map points; private String valueFilter = ""; @@ -168,11 +168,8 @@ public BasePoint getPointByClass(String pointClass) throws RdsCloudException { } @Nullable String pointId = indexClassToId.get(pointClass); - if (pointId instanceof String) { - BasePoint point = getPointById(pointId); - if (point instanceof BasePoint) { - return point; - } + if (pointId != null) { + return getPointById(pointId); } throw new RdsCloudException(String.format("pointClass \"%s\" not found", pointClass)); } @@ -181,11 +178,11 @@ public BasePoint getPointByClass(String pointClass) throws RdsCloudException { * public method: retrieve the data point with the given pointId */ public BasePoint getPointById(String pointId) throws RdsCloudException { - Map points = this.points; + Map points = this.points; if (points != null) { @Nullable BasePoint point = points.get(pointId); - if (point instanceof BasePoint) { + if (point != null) { return point; } } @@ -201,7 +198,7 @@ public String pointClassToId(String pointClass) throws RdsCloudException { } @Nullable String pointId = indexClassToId.get(pointClass); - if (pointId instanceof String) { + if (pointId != null) { return pointId; } throw new RdsCloudException(String.format("no pointId to match pointClass \"%s\"", pointClass)); @@ -262,13 +259,12 @@ public boolean refresh(String apiKey, String token) { } } - Map points = this.points; + Map points = this.points; if (points != null) { - for (Map.Entry entry : points.entrySet()) { + for (Map.Entry entry : points.entrySet()) { @Nullable - Object object = entry.getValue(); - if (object instanceof BasePoint) { - BasePoint point = (BasePoint) object; + BasePoint point = entry.getValue(); + if (point != null) { if ("Online".equals(point.getMemberName())) { set.add(String.format("\"%s\"", entry.getKey())); break; @@ -301,37 +297,27 @@ public boolean refresh(String apiKey, String token) { } @Nullable - Object newPoints = GSON.fromJson(json, RdsDataPoints.class); - - if (!(newPoints instanceof RdsDataPoints)) { - throw new RdsCloudException("new points list invalid"); - } + RdsDataPoints newPoints = GSON.fromJson(json, RdsDataPoints.class); - Map newPointsMap = ((RdsDataPoints) newPoints).points; + Map newPointsMap = newPoints.points; if (newPointsMap == null) { throw new RdsCloudException("new points map empty"); } synchronized (this) { - for (Map.Entry entry : newPointsMap.entrySet()) { + for (Entry entry : newPointsMap.entrySet()) { @Nullable String pointId = entry.getKey(); - if (!(pointId instanceof String)) { - throw new RdsCloudException("invalid new point id"); - } @Nullable - Object newPoint = entry.getValue(); - if (!(newPoint instanceof BasePoint)) { + BasePoint newPoint = entry.getValue(); + if (newPoint == null) { throw new RdsCloudException("invalid new point"); } @Nullable BasePoint myPoint = getPointById(pointId); - if (!(myPoint instanceof BasePoint)) { - throw new RdsCloudException("existing point not found"); - } if (!(newPoint.getClass().equals(myPoint.getClass()))) { throw new RdsCloudException("existing vs. new point class mismatch"); @@ -358,17 +344,16 @@ public boolean refresh(String apiKey, String token) { /* * initialize the second index into to the points Map */ - @SuppressWarnings("null") private void initClassToIdNameIndex() { - Map points = this.points; + Map points = this.points; if (points != null) { - indexClassToId = new HashMap<>(); - for (Entry entry : points.entrySet()) { + indexClassToId.clear(); + for (Entry entry : points.entrySet()) { @Nullable String pointKey = entry.getKey(); @Nullable BasePoint pointValue = entry.getValue(); - if (pointKey != null && pointValue != null) { + if (pointValue != null) { indexClassToId.put(pointValue.getPointClass(), pointKey); } } diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java index 2e8d0c8d09e73..467a05682aeda 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/points/PointDeserializer.java @@ -50,9 +50,9 @@ public BasePoint deserialize(@Nullable JsonElement element, @Nullable Type guff, JsonObject obj = element.getAsJsonObject(); JsonElement value = obj.get("value"); if (value == null) { - Object point = ctxt.deserialize(obj, UndefPoint.class); - if (point instanceof UndefPoint) { - return (UndefPoint) point; + UndefPoint point = ctxt.deserialize(obj, UndefPoint.class); + if (point != null) { + return point; } throw new JsonSyntaxException("unable to parse point WITHOUT a \"value\" element"); } @@ -84,33 +84,33 @@ public BasePoint deserialize(@Nullable JsonElement element, @Nullable Type guff, pointType = PointType.NESTED_NUMBER; } - Object point; + BasePoint point; switch (pointType) { case STRING: { point = ctxt.deserialize(obj, StringPoint.class); - if (point instanceof StringPoint) { - return (StringPoint) point; + if (point != null) { + return point; } break; } case NESTED_NUMBER: { point = ctxt.deserialize(obj, NestedNumberPoint.class); - if (point instanceof NestedNumberPoint) { - return (NestedNumberPoint) point; + if (point != null) { + return point; } break; } case NUMBER: { point = ctxt.deserialize(obj, NumberPoint.class); - if (point instanceof NumberPoint) { - return (NumberPoint) point; + if (point != null) { + return point; } break; } default: { point = ctxt.deserialize(obj, UndefPoint.class); - if (point instanceof UndefPoint) { - return (UndefPoint) point; + if (point != null) { + return point; } } } 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/RdsTestData.java index dd75d5335a4a8..ecf644f485f39 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/RdsTestData.java @@ -65,16 +65,7 @@ private String load(String fileName) { } @Test - public void test() { - confirmDegreeSymbolCodingNotTrashed(); - testAccessToken(); - testRdsPlants(); - testRdsDataPointsFull(); - testRdsDataPointsFullNew(); - testRdsDataPointsRefresh(); - } - - private void testRdsDataPointsFullNew() { + public void testRdsDataPointsFullNew() { RdsDataPoints dataPoints = RdsDataPoints.createFromJson(load("datapoints_full_set_new")); assertNotNull(dataPoints); try { @@ -83,12 +74,13 @@ private void testRdsDataPointsFullNew() { fail(e.getMessage()); } @Nullable - Map points = dataPoints.points; + Map points = dataPoints.points; assertNotNull(points); assertEquals(70, points.size()); } - private void confirmDegreeSymbolCodingNotTrashed() { + @Test + public void confirmDegreeSymbolCodingNotTrashed() { /* * note: temperature symbols with a degree sign: the MVN Spotless trashes the * "degree" (looks like *) symbol, so we must escape these symbols as octal \260 @@ -101,12 +93,13 @@ private void confirmDegreeSymbolCodingNotTrashed() { assertTrue(BasePoint.DEGREES_FAHRENHEIT.startsWith(BasePoint.DEGREES_CELSIUS.substring(0, 1))); } - private void testRdsDataPointsRefresh() { + @Test + public void testRdsDataPointsRefresh() { RdsDataPoints refreshPoints = RdsDataPoints.createFromJson(load("datapoints_refresh_set")); assertNotNull(refreshPoints); assertNotNull(refreshPoints.points); - Map refreshMap = refreshPoints.points; + Map refreshMap = refreshPoints.points; assertNotNull(refreshMap); @Nullable @@ -185,7 +178,7 @@ private void testRdsDataPointsRefresh() { assertNotNull(originalPoints.points); // check that the refresh point types match the originals - Map originalMap = originalPoints.points; + Map originalMap = originalPoints.points; assertNotNull(originalMap); @Nullable BasePoint refreshPoint; @@ -200,7 +193,8 @@ private void testRdsDataPointsRefresh() { } } - private void testAccessToken() { + @Test + public void testAccessToken() { RdsAccessToken accessToken = RdsAccessToken.createFromJson(load("access_token")); assertNotNull(accessToken); try { @@ -211,7 +205,8 @@ private void testAccessToken() { assertTrue(accessToken.isExpired()); } - private void testRdsDataPointsFull() { + @Test + public void testRdsDataPointsFull() { RdsDataPoints dataPoints = RdsDataPoints.createFromJson(load("datapoints_full_set")); assertNotNull(dataPoints); try { @@ -221,7 +216,7 @@ private void testRdsDataPointsFull() { } @Nullable - Map points = dataPoints.points; + Map points = dataPoints.points; assertNotNull(points); assertEquals(67, points.size()); @@ -366,15 +361,15 @@ private void testRdsDataPointsFull() { try { // test the all-the-way-round lookup loop assertNotNull(dataPoints.points); - Map pointsMap = dataPoints.points; + Map pointsMap = dataPoints.points; assertNotNull(pointsMap); @Nullable - Object point; - for (Entry entry : pointsMap.entrySet()) { + BasePoint point; + for (Entry entry : pointsMap.entrySet()) { point = entry.getValue(); assertTrue(point instanceof BasePoint); // ignore UNDEF points where all-the-way-round lookup fails - if (!"UNDEF".equals(((BasePoint) point).getState().toString())) { + if (!"UNDEF".equals(point.getState().toString())) { @Nullable String x = entry.getKey(); assertNotNull(x); @@ -490,20 +485,22 @@ private void testRdsDataPointsFull() { } } - @SuppressWarnings("null") - private void testRdsPlants() { + @Test + public void testRdsPlants() { try { RdsPlants plants = RdsPlants.createFromJson(load("plants")); assertNotNull(plants); + @Nullable List plantList = plants.getPlants(); assertNotNull(plantList); - Object plant; + @Nullable + PlantInfo plant; plant = plantList.get(0); assertTrue(plant instanceof PlantInfo); assertEquals("Pd1774247-7de7-4896-ac76-b7e0dd943c40", ((PlantInfo) plant).getId()); - assertTrue(((PlantInfo) plant).isOnline()); + assertTrue(plant.isOnline()); plant = plantList.get(1); assertTrue(plant instanceof PlantInfo); From ae9a4f64f65e5e91853aafa56e2aa6e7f33c1e8e Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Tue, 26 May 2020 17:13:58 +0100 Subject: [PATCH 4/4] [siemensrds] removed orphan semi- colons Signed-off-by: Andrew Fiddian-Green --- .../org/openhab/binding/siemensrds/internal/RdsCloudHandler.java | 1 - .../java/org/openhab/binding/siemensrds/internal/RdsHandler.java | 1 - 2 files changed, 2 deletions(-) diff --git a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java index df1b5d1dddac5..abca0064d80c0 100644 --- a/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java +++ b/bundles/org.openhab.binding.siemensrds/src/main/java/org/openhab/binding/siemensrds/internal/RdsCloudHandler.java @@ -128,7 +128,6 @@ private synchronized void refreshToken() { } accessToken = this.accessToken = RdsAccessToken.createFromJson(json); - ; } catch (RdsCloudException e) { logger.warn(LOG_SYSTEM_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage()); } catch (JsonParseException | IOException e) { 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 1293344267612..b9f702933621c 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 @@ -126,7 +126,6 @@ public void initializePolling() { } startFastPollingBurst(); - ; } catch (RdsCloudException e) { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage()); logger.warn(LOG_SYSTEM_EXCEPTION, "initializePolling()", e.getClass().getName(), e.getMessage());