import java.util.Objects;
import java.util.concurrent.Future;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.homematic.internal.HomematicBindingConstants;
import org.openhab.binding.homematic.internal.common.HomematicConfig;
import org.openhab.binding.homematic.internal.communicator.HomematicGateway;
loadHomematicChannelValues(channel);
for (HmDatapoint dp : channel.getDatapoints()) {
if (dp.getParamsetType() == HmParamsetType.MASTER) {
- config.put(MetadataUtils.getParameterName(dp),
- dp.isEnumType() ? dp.getOptionValue() : dp.getValue());
+ config.put(MetadataUtils.getParameterName(dp), getValueForConfiguration(dp));
}
}
}
if (dp.getParamsetType() == HmParamsetType.MASTER) {
// update configuration
Configuration config = editConfiguration();
- config.put(MetadataUtils.getParameterName(dp), dp.isEnumType() ? dp.getOptionValue() : dp.getValue());
+ config.put(MetadataUtils.getParameterName(dp), getValueForConfiguration(dp));
updateConfiguration(config);
} else if (!HomematicTypeGeneratorImpl.isIgnoredDatapoint(dp)) {
// update channel
}
}
+ private @Nullable Object getValueForConfiguration(HmDatapoint dp) {
+ if (dp.getValue() == null) {
+ return null;
+ }
+ if (dp.isEnumType()) {
+ return dp.getOptionValue();
+ }
+ if (dp.isNumberType()) {
+ // For number datapoints that are only used depending on the value of other datapoints,
+ // the CCU may return invalid (out of range) values if the datapoint currently is not in use.
+ // Make sure to not invalidate the whole configuration by returning the datapoint's default
+ // value in that case.
+ final boolean minValid, maxValid;
+ if (dp.isFloatType()) {
+ Double numValue = dp.getDoubleValue();
+ minValid = dp.getMinValue() == null || numValue >= dp.getMinValue().doubleValue();
+ maxValid = dp.getMaxValue() == null || numValue <= dp.getMaxValue().doubleValue();
+ } else {
+ Integer numValue = dp.getIntegerValue();
+ minValid = dp.getMinValue() == null || numValue >= dp.getMinValue().intValue();
+ maxValid = dp.getMaxValue() == null || numValue <= dp.getMaxValue().intValue();
+ }
+ if (minValid && maxValid) {
+ return dp.getValue();
+ }
+ logger.warn("Value for datapoint {} is outside of valid range, using default value for config.", dp);
+ return dp.getDefaultValue();
+ }
+ return dp.getValue();
+ }
+
/**
* Converts the value of the datapoint to a State, updates the channel and also sets the thing status if necessary.
*/
*/
package org.openhab.binding.homematic.internal.model;
+import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.homematic.internal.misc.MiscUtils;
/**
/**
* Returns the value of a option list.
*/
- public String getOptionValue() {
- if (options != null && value != null) {
- int idx = 0;
- if (value instanceof Integer) {
- idx = (int) value;
- } else {
- idx = Integer.parseInt(value.toString());
- }
- if (idx < options.length) {
- return options[idx];
- }
+ public @Nullable String getOptionValue() {
+ Integer idx = getIntegerValue();
+ if (options != null && idx != null && idx < options.length) {
+ return options[idx];
}
return null;
}
+ public @Nullable Integer getIntegerValue() {
+ if (value instanceof Integer) {
+ return (int) value;
+ } else if (value != null) {
+ return Integer.parseInt(value.toString());
+ } else {
+ return null;
+ }
+ }
+
+ public @Nullable Double getDoubleValue() {
+ if (value instanceof Double) {
+ return (double) value;
+ } else if (value != null) {
+ return Double.parseDouble(value.toString());
+ } else {
+ return null;
+ }
+ }
+
/**
* Returns the max value.
*/