2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.homematic.internal.converter.type;
15 import org.openhab.binding.homematic.internal.converter.ConverterException;
16 import org.openhab.binding.homematic.internal.model.HmDatapoint;
17 import org.openhab.binding.homematic.internal.model.HmInterface;
18 import org.openhab.binding.homematic.internal.type.MetadataUtils;
19 import org.openhab.core.library.types.IncreaseDecreaseType;
20 import org.openhab.core.library.types.OnOffType;
21 import org.openhab.core.library.types.PercentType;
22 import org.openhab.core.library.types.UpDownType;
23 import org.openhab.core.types.Command;
24 import org.openhab.core.types.Type;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Converts between a Homematic datapoint value and an openHAB PercentType.
31 * @author Gerhard Riegler - Initial contribution
33 public class PercentTypeConverter extends AbstractTypeConverter<PercentType> {
34 private final Logger logger = LoggerFactory.getLogger(PercentTypeConverter.class);
37 protected Object commandToBinding(Command command, HmDatapoint dp) throws ConverterException {
38 if (command.getClass() == IncreaseDecreaseType.class) {
39 PercentType type = convertFromBinding(dp);
41 int percent = type.intValue();
42 percent += command.equals(IncreaseDecreaseType.INCREASE) ? 10 : -10;
43 percent = (percent / 10) * 10;
44 percent = Math.min(100, percent);
45 percent = Math.max(0, percent);
46 return convertToBinding(new PercentType(percent), dp);
47 } else if (command.getClass() == OnOffType.class) {
48 PercentType type = new PercentType(command.equals(OnOffType.ON) ? 100 : 0);
49 return convertToBinding(type, dp);
50 } else if (command.getClass() == UpDownType.class) {
51 return convertToBinding(command.equals(UpDownType.UP) ? PercentType.ZERO : PercentType.HUNDRED, dp);
53 return super.commandToBinding(command, dp);
57 private double getCorrectedMaxValue(HmDatapoint dp) {
58 double max = dp.getMaxValue().doubleValue();
59 return (max == 1.01 && dp.getChannel().getDevice().getHmInterface() == HmInterface.HMIP ? 1.0d : max);
63 protected boolean toBindingValidation(HmDatapoint dp, Class<? extends Type> typeClass) {
64 return dp.isNumberType() && dp.getMaxValue() != null && dp.getMinValue() != null
65 && dp.getChannel().getType() != null && typeClass.isAssignableFrom(PercentType.class);
69 protected Object toBinding(PercentType type, HmDatapoint dp) throws ConverterException {
70 double maxValue = getCorrectedMaxValue(dp);
71 Double number = (type.doubleValue() / 100) * maxValue;
73 if (MetadataUtils.isRollerShutter(dp)) {
74 if (PercentType.HUNDRED.equals(type)) { // means DOWN
75 return dp.getMinValue().doubleValue();
76 } else if (PercentType.ZERO.equals(type)) { // means UP
79 return maxValue - number;
81 if (number < 0.0 || number > 100.0) {
82 logger.warn("Percent value '{}' out of range, truncating value for {}", number, dp);
83 number = number < 0.0 ? 0.0 : 100.0;
85 if (dp.isIntegerType()) {
86 return number.intValue();
88 return round(number).doubleValue();
92 protected boolean fromBindingValidation(HmDatapoint dp) {
93 return dp.isNumberType() && dp.getValue() instanceof Number && dp.getMaxValue() != null
94 && dp.getChannel().getType() != null;
98 protected PercentType fromBinding(HmDatapoint dp) throws ConverterException {
99 Double number = ((Number) dp.getValue()).doubleValue();
100 int percent = (int) (100 / getCorrectedMaxValue(dp) * number);
102 logger.warn("Percent value '{}' out of range, truncating value for {}", number, dp);
105 if (MetadataUtils.isRollerShutter(dp)) {
106 percent = 100 - percent;
108 return new PercentType(percent);