[homematic] Adjust warning if current value is out of range (#19284)

* [homematic] Handle special values when assembling config

For numeric data points, the central can send us values with special
meaning whose value is outside of the min...max range. Accept such
values while saving configuration.

Signed-off-by: Danny Baumann <dannybaumann@web.de>
This commit is contained in:
maniac103
2025-09-05 17:27:32 +02:00
committed by GitHub
parent 28610e05bc
commit 8cf841df14
5 changed files with 56 additions and 6 deletions
@@ -43,7 +43,7 @@ public class CcuParamsetDescriptionParser extends CommonRpcParser<TclScriptDataL
for (TclScriptDataEntry entry : resultList.getEntries()) {
HmDatapoint dp = assembleDatapoint(entry.name, entry.unit, entry.valueType,
this.toOptionList(entry.options), convertToType(entry.minValue), convertToType(entry.maxValue),
toInteger(entry.operations), convertToType(entry.value), paramsetType, isHmIpDevice);
toInteger(entry.operations), convertToType(entry.value), null, paramsetType, isHmIpDevice);
channel.addDatapoint(dp);
}
}
@@ -13,6 +13,7 @@
package org.openhab.binding.homematic.internal.communicator.parser;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNull;
@@ -167,8 +168,8 @@ public abstract class CommonRpcParser<M, R> implements RpcParser<M, R> {
* Assembles a datapoint with the given parameters.
*/
protected HmDatapoint assembleDatapoint(String name, String unit, String type, String[] options, Object min,
Object max, Integer operations, Object defaultValue, HmParamsetType paramsetType, boolean isHmIpDevice)
throws IOException {
Object max, Integer operations, Object defaultValue, Map<String, Number> specialValues,
HmParamsetType paramsetType, boolean isHmIpDevice) throws IOException {
HmDatapoint dp = new HmDatapoint();
dp.setName(name);
dp.setDescription(name);
@@ -220,6 +221,9 @@ public abstract class CommonRpcParser<M, R> implements RpcParser<M, R> {
} else {
dp.setDefaultValue(convertToType(dp, defaultValue));
}
if (dp.isNumberType() && specialValues != null) {
dp.setSpecialValues(specialValues);
}
dp.setValue(dp.getDefaultValue());
return dp;
}
@@ -13,6 +13,7 @@
package org.openhab.binding.homematic.internal.communicator.parser;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.openhab.binding.homematic.internal.model.HmChannel;
@@ -53,11 +54,30 @@ public class GetParamsetDescriptionParser extends CommonRpcParser<Object[], Void
HmDatapoint dp = assembleDatapoint(datapointName, toString(dpMeta.get("UNIT")),
toString(dpMeta.get("TYPE")), toOptionList(dpMeta.get("VALUE_LIST")), dpMeta.get("MIN"),
dpMeta.get("MAX"), toInteger(dpMeta.get("OPERATIONS")), dpMeta.get("DEFAULT"), paramsetType,
isHmIpDevice);
dpMeta.get("MAX"), toInteger(dpMeta.get("OPERATIONS")), dpMeta.get("DEFAULT"),
toSpecialValues(dpMeta.get("SPECIAL")), paramsetType, isHmIpDevice);
channel.addDatapoint(dp);
}
return null;
}
private Map<String, Number> toSpecialValues(Object specialValues) {
if (specialValues != null && specialValues instanceof Object[] array) {
Map<String, Number> result = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if (array[i] instanceof Map itemMap) {
String id = (String) itemMap.get("ID");
Object value = itemMap.get("VALUE");
if (id != null && value instanceof Number number) {
result.put(id, number);
}
}
}
if (!result.isEmpty()) {
return result;
}
}
return null;
}
}
@@ -447,7 +447,19 @@ public class HomematicThingHandler extends BaseThingHandler {
if (minValid && maxValid) {
return dp.getValue();
}
logger.warn("Value for datapoint {} is outside of valid range, using default value for config.", dp);
Map<String, Number> specialValues = dp.getSpecialValues();
if (specialValues != null) {
Number value = dp.isFloatType() ? dp.getDoubleValue() : dp.getIntegerValue();
for (Number special : specialValues.values()) {
if (value.equals(special)) {
return dp.getValue();
}
}
}
logger.warn(
"Value for datapoint {} of device {} is outside of valid range, using default value for config.",
dp, dp.getChannel().getDevice().getAddress());
return dp.getDefaultValue();
}
return dp.getValue();
@@ -12,6 +12,8 @@
*/
package org.openhab.binding.homematic.internal.model;
import java.util.Map;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.homematic.internal.misc.MiscUtils;
@@ -32,6 +34,7 @@ public class HmDatapoint implements Cloneable {
private HmParamsetType paramsetType;
private Number minValue;
private Number maxValue;
private Map<String, Number> specialValues;
private String[] options;
private boolean readOnly;
private boolean readable;
@@ -303,6 +306,17 @@ public class HmDatapoint implements Cloneable {
this.defaultValue = defaultValue;
}
/**
* Sets map of values with special meaning
*/
public void setSpecialValues(Map<String, Number> specialValues) {
this.specialValues = specialValues;
}
public Map<String, Number> getSpecialValues() {
return specialValues;
}
/**
* Returns true, if the datapoint is a virtual datapoint.
*/