]> git.basschouten.com Git - openhab-addons.git/commitdiff
fix Fahrenheit conversion (#12024)
authoreugen <freiter@gmail.com>
Fri, 14 Jan 2022 21:56:50 +0000 (22:56 +0100)
committerGitHub <noreply@github.com>
Fri, 14 Jan 2022 21:56:50 +0000 (22:56 +0100)
Signed-off-by: Eugen Freiter <freiter@gmx.de>
bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/AbstractHomekitAccessoryImpl.java
bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCharacteristicFactory.java
bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitHeaterCoolerImpl.java
bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitTemperatureSensorImpl.java
bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitThermostatImpl.java

index 774533086027ac6a363384300fbccca425b95a51..34dac4e48242815fb2cf1e62e120c54a0df06a71 100644 (file)
@@ -12,8 +12,6 @@
  */
 package org.openhab.io.homekit.internal.accessories;
 
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -22,9 +20,6 @@ import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
-import javax.measure.Quantity;
-import javax.measure.Unit;
-
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.items.GenericItem;
@@ -32,8 +27,6 @@ import org.openhab.core.items.Item;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.OpenClosedType;
 import org.openhab.core.library.types.StringType;
-import org.openhab.core.library.unit.ImperialUnits;
-import org.openhab.core.library.unit.SIUnits;
 import org.openhab.core.types.State;
 import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
 import org.openhab.io.homekit.internal.HomekitCharacteristicType;
@@ -282,32 +275,13 @@ abstract class AbstractHomekitAccessoryImpl implements HomekitAccessory {
         characteristics.add(characteristic);
     }
 
-    @NonNullByDefault
-    private <T extends Quantity<T>> double convertAndRound(double value, Unit<T> from, Unit<T> to) {
-        double rawValue = from.equals(to) ? value : from.getConverterTo(to).convert(value);
-        return new BigDecimal(rawValue).setScale(1, RoundingMode.HALF_UP).doubleValue();
-    }
-
-    @NonNullByDefault
-    protected double convertToCelsius(double degrees) {
-        return convertAndRound(degrees,
-                getSettings().useFahrenheitTemperature ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS, SIUnits.CELSIUS);
-    }
-
-    @NonNullByDefault
-    protected double convertFromCelsius(double degrees) {
-        return convertAndRound(degrees,
-                getSettings().useFahrenheitTemperature ? SIUnits.CELSIUS : ImperialUnits.FAHRENHEIT,
-                ImperialUnits.FAHRENHEIT);
-    }
-
     /**
      * create boolean reader with ON state mapped to trueOnOffValue or trueOpenClosedValue depending of item type
      *
      * @param characteristicType characteristic id
      * @param trueOnOffValue ON value for switch
      * @param trueOpenClosedValue ON value for contact
-     * @return boolean readed
+     * @return boolean read
      * @throws IncompleteAccessoryException
      */
     @NonNullByDefault
index 8a3fb18efdcde740d17179f402e03b2c158f4d16..8094f13ae1fd51211b29dc55ad2920456430d83e 100644 (file)
@@ -15,6 +15,7 @@ package org.openhab.io.homekit.internal.accessories;
 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.*;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -22,6 +23,9 @@ import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
+import javax.measure.Quantity;
+import javax.measure.Unit;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.items.GenericItem;
@@ -35,13 +39,18 @@ import org.openhab.core.library.types.HSBType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.OpenClosedType;
 import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.unit.ImperialUnits;
+import org.openhab.core.library.unit.SIUnits;
 import org.openhab.core.types.State;
 import org.openhab.core.types.UnDefType;
+import org.openhab.io.homekit.Homekit;
 import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
 import org.openhab.io.homekit.internal.HomekitCharacteristicType;
 import org.openhab.io.homekit.internal.HomekitCommandType;
 import org.openhab.io.homekit.internal.HomekitException;
+import org.openhab.io.homekit.internal.HomekitImpl;
 import org.openhab.io.homekit.internal.HomekitTaggedItem;
+import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -170,6 +179,12 @@ public class HomekitCharacteristicFactory {
     // METHODS TO CREATE SINGLE CHARACTERISTIC FROM OH ITEM
 
     // supporting methods
+
+    public static boolean useFahrenheit() {
+        return FrameworkUtil.getBundle(HomekitImpl.class).getBundleContext()
+                .getServiceReference(Homekit.class.getName()).getProperty("useFahrenheitTemperature") == Boolean.TRUE;
+    }
+
     private static <T extends CharacteristicEnum> CompletableFuture<T> getEnumFromItem(HomekitTaggedItem item,
             T offEnum, T onEnum, T defaultEnum) {
         final State state = item.getItem().getState();
@@ -239,6 +254,19 @@ public class HomekitCharacteristicFactory {
         return value;
     }
 
+    private static <T extends Quantity<T>> double convertAndRound(double value, Unit<T> from, Unit<T> to) {
+        double rawValue = from.equals(to) ? value : from.getConverterTo(to).convert(value);
+        return new BigDecimal(rawValue).setScale(1, RoundingMode.HALF_UP).doubleValue();
+    }
+
+    public static double convertToCelsius(double degrees) {
+        return convertAndRound(degrees, useFahrenheit() ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS, SIUnits.CELSIUS);
+    }
+
+    public static double convertFromCelsius(double degrees) {
+        return convertAndRound(degrees, SIUnits.CELSIUS, useFahrenheit() ? ImperialUnits.FAHRENHEIT : SIUnits.CELSIUS);
+    }
+
     private static Supplier<CompletableFuture<Integer>> getAngleSupplier(HomekitTaggedItem taggedItem,
             int defaultValue) {
         return () -> CompletableFuture.completedFuture(getAngleFromItem(taggedItem, defaultValue));
@@ -305,6 +333,26 @@ public class HomekitCharacteristicFactory {
         };
     }
 
+    private static Supplier<CompletableFuture<Double>> getTemperatureSupplier(HomekitTaggedItem taggedItem,
+            double defaultValue) {
+        return () -> {
+            final @Nullable DecimalType value = taggedItem.getItem().getStateAs(DecimalType.class);
+            return CompletableFuture
+                    .completedFuture(value != null ? convertToCelsius(value.doubleValue()) : defaultValue);
+        };
+    }
+
+    private static ExceptionalConsumer<Double> setTemperatureConsumer(HomekitTaggedItem taggedItem) {
+        return (value) -> {
+            if (taggedItem.getItem() instanceof NumberItem) {
+                ((NumberItem) taggedItem.getItem()).send(new DecimalType(convertFromCelsius(value)));
+            } else {
+                logger.warn("Item type {} is not supported for {}. Only Number type is supported.",
+                        taggedItem.getItem().getType(), taggedItem.getName());
+            }
+        };
+    }
+
     protected static Consumer<HomekitCharacteristicChangeCallback> getSubscriber(HomekitTaggedItem taggedItem,
             HomekitCharacteristicType key, HomekitAccessoryUpdater updater) {
         return (callback) -> updater.subscribe((GenericItem) taggedItem.getItem(), key.getTag(), callback);
@@ -631,10 +679,10 @@ public class HomekitCharacteristicFactory {
                         CoolingThresholdTemperatureCharacteristic.DEFAULT_MAX_VALUE),
                 taggedItem.getConfigurationAsDouble(HomekitTaggedItem.STEP,
                         CoolingThresholdTemperatureCharacteristic.DEFAULT_STEP),
-                getDoubleSupplier(taggedItem,
+                getTemperatureSupplier(taggedItem,
                         taggedItem.getConfigurationAsDouble(HomekitTaggedItem.MIN_VALUE,
                                 CoolingThresholdTemperatureCharacteristic.DEFAULT_MIN_VALUE)),
-                setDoubleConsumer(taggedItem), getSubscriber(taggedItem, COOLING_THRESHOLD_TEMPERATURE, updater),
+                setTemperatureConsumer(taggedItem), getSubscriber(taggedItem, COOLING_THRESHOLD_TEMPERATURE, updater),
                 getUnsubscriber(taggedItem, COOLING_THRESHOLD_TEMPERATURE, updater));
     }
 
@@ -647,10 +695,10 @@ public class HomekitCharacteristicFactory {
                         HeatingThresholdTemperatureCharacteristic.DEFAULT_MAX_VALUE),
                 taggedItem.getConfigurationAsDouble(HomekitTaggedItem.STEP,
                         HeatingThresholdTemperatureCharacteristic.DEFAULT_STEP),
-                getDoubleSupplier(taggedItem,
+                getTemperatureSupplier(taggedItem,
                         taggedItem.getConfigurationAsDouble(HomekitTaggedItem.MIN_VALUE,
                                 HeatingThresholdTemperatureCharacteristic.DEFAULT_MIN_VALUE)),
-                setDoubleConsumer(taggedItem), getSubscriber(taggedItem, HEATING_THRESHOLD_TEMPERATURE, updater),
+                setTemperatureConsumer(taggedItem), getSubscriber(taggedItem, HEATING_THRESHOLD_TEMPERATURE, updater),
                 getUnsubscriber(taggedItem, HEATING_THRESHOLD_TEMPERATURE, updater));
     }
 
index bb3ad0f77f41d575fad25eab86c518064960a058..43aa8e2caebdd3575c7f7a8ba01bdb8497b84d0f 100644 (file)
@@ -108,9 +108,12 @@ public class HomekitHeaterCoolerImpl extends AbstractHomekitAccessoryImpl implem
     public CompletableFuture<Double> getCurrentTemperature() {
         final @Nullable DecimalType state = getStateAs(HomekitCharacteristicType.CURRENT_TEMPERATURE,
                 DecimalType.class);
-        return CompletableFuture.completedFuture(state != null ? convertToCelsius(state.doubleValue())
+        return CompletableFuture.completedFuture(state != null
+                ? HomekitCharacteristicFactory.convertToCelsius(state.doubleValue())
                 : getAccessoryConfiguration(HomekitCharacteristicType.CURRENT_TEMPERATURE, HomekitTaggedItem.MIN_VALUE,
-                        BigDecimal.valueOf(CurrentTemperatureCharacteristic.DEFAULT_MIN_VALUE)).doubleValue());
+                        BigDecimal.valueOf(HomekitCharacteristicFactory
+                                .convertFromCelsius(CurrentTemperatureCharacteristic.DEFAULT_MIN_VALUE)))
+                                        .doubleValue());
     }
 
     @Override
@@ -151,7 +154,7 @@ public class HomekitHeaterCoolerImpl extends AbstractHomekitAccessoryImpl implem
 
     public CompletableFuture<TemperatureDisplayUnitEnum> getTemperatureDisplayUnit() {
         return CompletableFuture
-                .completedFuture(getSettings().useFahrenheitTemperature ? TemperatureDisplayUnitEnum.FAHRENHEIT
+                .completedFuture(HomekitCharacteristicFactory.useFahrenheit() ? TemperatureDisplayUnitEnum.FAHRENHEIT
                         : TemperatureDisplayUnitEnum.CELSIUS);
     }
 
index c20574247abacb59883793964cd7e4ea0b02aca3..2071409757c09b2fbdf60cc3654762066958385a 100644 (file)
@@ -25,6 +25,7 @@ import org.openhab.io.homekit.internal.HomekitTaggedItem;
 
 import io.github.hapjava.accessories.TemperatureSensorAccessory;
 import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
+import io.github.hapjava.characteristics.impl.thermostat.CurrentTemperatureCharacteristic;
 import io.github.hapjava.characteristics.impl.thermostat.TargetTemperatureCharacteristic;
 import io.github.hapjava.services.impl.TemperatureSensorService;
 
@@ -46,7 +47,8 @@ class HomekitTemperatureSensorImpl extends AbstractHomekitAccessoryImpl implemen
         final @Nullable DecimalType state = getStateAs(HomekitCharacteristicType.CURRENT_TEMPERATURE,
                 DecimalType.class);
         return CompletableFuture
-                .completedFuture(state != null ? convertToCelsius(state.doubleValue()) : getMinCurrentTemperature());
+                .completedFuture(state != null ? HomekitCharacteristicFactory.convertToCelsius(state.doubleValue())
+                        : getMinCurrentTemperature());
     }
 
     @Override
@@ -56,16 +58,23 @@ class HomekitTemperatureSensorImpl extends AbstractHomekitAccessoryImpl implemen
 
     @Override
     public double getMinCurrentTemperature() {
-        return convertToCelsius(
+        // Apple defines default values in Celsius. We need to convert them to Fahrenheit if openHAB is using Fahrenheit
+        // convertToCelsius and convertFromCelsius are only converting if useFahrenheit is set to true, so no additional
+        // check here needed
+        return HomekitCharacteristicFactory.convertToCelsius(
                 getAccessoryConfiguration(HomekitCharacteristicType.CURRENT_TEMPERATURE, HomekitTaggedItem.MIN_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MIN_VALUE)).doubleValue());
+                        BigDecimal.valueOf(HomekitCharacteristicFactory
+                                .convertFromCelsius(CurrentTemperatureCharacteristic.DEFAULT_MIN_VALUE)))
+                                        .doubleValue());
     }
 
     @Override
     public double getMaxCurrentTemperature() {
-        return convertToCelsius(
+        return HomekitCharacteristicFactory.convertToCelsius(
                 getAccessoryConfiguration(HomekitCharacteristicType.CURRENT_TEMPERATURE, HomekitTaggedItem.MAX_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MAX_VALUE)).doubleValue());
+                        BigDecimal.valueOf(HomekitCharacteristicFactory
+                                .convertFromCelsius(CurrentTemperatureCharacteristic.DEFAULT_MAX_VALUE)))
+                                        .doubleValue());
     }
 
     @Override
index 5c14a4ae9c9c5fe0a0e1bd7a49480c63ed0b701d..105f0b1bb0bd21144f7c0b2db384783270da4453 100644 (file)
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
 import io.github.hapjava.accessories.ThermostatAccessory;
 import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
 import io.github.hapjava.characteristics.impl.thermostat.CurrentHeatingCoolingStateEnum;
+import io.github.hapjava.characteristics.impl.thermostat.CurrentTemperatureCharacteristic;
 import io.github.hapjava.characteristics.impl.thermostat.TargetHeatingCoolingStateEnum;
 import io.github.hapjava.characteristics.impl.thermostat.TargetTemperatureCharacteristic;
 import io.github.hapjava.characteristics.impl.thermostat.TemperatureDisplayUnitEnum;
@@ -106,21 +107,31 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
     @Override
     public CompletableFuture<Double> getCurrentTemperature() {
         DecimalType state = getStateAs(HomekitCharacteristicType.CURRENT_TEMPERATURE, DecimalType.class);
-        return CompletableFuture.completedFuture(state != null ? convertToCelsius(state.doubleValue()) : 0.0);
+        return CompletableFuture
+                .completedFuture(state != null ? HomekitCharacteristicFactory.convertToCelsius(state.doubleValue())
+                        : getMinCurrentTemperature());
     }
 
     @Override
     public double getMinCurrentTemperature() {
-        return convertToCelsius(
+        // Apple defines default values in Celsius. We need to convert them to Fahrenheit if openHAB is using Fahrenheit
+        // convertToCelsius and convertFromCelsius are only converting if useFahrenheit is set to true, so no additional
+        // check here needed
+
+        return HomekitCharacteristicFactory.convertToCelsius(
                 getAccessoryConfiguration(HomekitCharacteristicType.CURRENT_TEMPERATURE, HomekitTaggedItem.MIN_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MIN_VALUE)).doubleValue());
+                        BigDecimal.valueOf(HomekitCharacteristicFactory
+                                .convertFromCelsius(CurrentTemperatureCharacteristic.DEFAULT_MIN_VALUE)))
+                                        .doubleValue());
     }
 
     @Override
     public double getMaxCurrentTemperature() {
-        return convertToCelsius(
+        return HomekitCharacteristicFactory.convertToCelsius(
                 getAccessoryConfiguration(HomekitCharacteristicType.CURRENT_TEMPERATURE, HomekitTaggedItem.MAX_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MAX_VALUE)).doubleValue());
+                        BigDecimal.valueOf(HomekitCharacteristicFactory
+                                .convertFromCelsius(CurrentTemperatureCharacteristic.DEFAULT_MAX_VALUE)))
+                                        .doubleValue());
     }
 
     @Override
@@ -138,7 +149,7 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
     @Override
     public CompletableFuture<TemperatureDisplayUnitEnum> getTemperatureDisplayUnit() {
         return CompletableFuture
-                .completedFuture(getSettings().useFahrenheitTemperature ? TemperatureDisplayUnitEnum.FAHRENHEIT
+                .completedFuture(HomekitCharacteristicFactory.useFahrenheit() ? TemperatureDisplayUnitEnum.FAHRENHEIT
                         : TemperatureDisplayUnitEnum.CELSIUS);
     }
 
@@ -150,7 +161,8 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
     @Override
     public CompletableFuture<Double> getTargetTemperature() {
         DecimalType state = getStateAs(HomekitCharacteristicType.TARGET_TEMPERATURE, DecimalType.class);
-        return CompletableFuture.completedFuture(state != null ? convertToCelsius(state.doubleValue()) : 0.0);
+        return CompletableFuture.completedFuture(
+                state != null ? HomekitCharacteristicFactory.convertToCelsius(state.doubleValue()) : 0.0);
     }
 
     @Override
@@ -165,7 +177,7 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
                 HomekitCharacteristicType.TARGET_TEMPERATURE);
         if (characteristic.isPresent()) {
             ((NumberItem) characteristic.get().getItem())
-                    .send(new DecimalType(BigDecimal.valueOf(convertFromCelsius(value))));
+                    .send(new DecimalType(BigDecimal.valueOf(HomekitCharacteristicFactory.convertFromCelsius(value))));
         } else {
             logger.warn("Missing mandatory characteristic {}", HomekitCharacteristicType.TARGET_TEMPERATURE);
         }
@@ -173,16 +185,24 @@ class HomekitThermostatImpl extends AbstractHomekitAccessoryImpl implements Ther
 
     @Override
     public double getMinTargetTemperature() {
-        return convertToCelsius(
-                getAccessoryConfiguration(HomekitCharacteristicType.TARGET_TEMPERATURE, HomekitTaggedItem.MIN_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MIN_VALUE)).doubleValue());
+        return HomekitCharacteristicFactory
+                .convertToCelsius(
+                        getAccessoryConfiguration(HomekitCharacteristicType.TARGET_TEMPERATURE,
+                                HomekitTaggedItem.MIN_VALUE,
+                                BigDecimal.valueOf(HomekitCharacteristicFactory
+                                        .convertFromCelsius(TargetTemperatureCharacteristic.DEFAULT_MIN_VALUE)))
+                                                .doubleValue());
     }
 
     @Override
     public double getMaxTargetTemperature() {
-        return convertToCelsius(
-                getAccessoryConfiguration(HomekitCharacteristicType.TARGET_TEMPERATURE, HomekitTaggedItem.MAX_VALUE,
-                        BigDecimal.valueOf(TargetTemperatureCharacteristic.DEFAULT_MAX_VALUE)).doubleValue());
+        return HomekitCharacteristicFactory
+                .convertToCelsius(
+                        getAccessoryConfiguration(HomekitCharacteristicType.TARGET_TEMPERATURE,
+                                HomekitTaggedItem.MAX_VALUE,
+                                BigDecimal.valueOf(HomekitCharacteristicFactory
+                                        .convertFromCelsius(TargetTemperatureCharacteristic.DEFAULT_MAX_VALUE)))
+                                                .doubleValue());
     }
 
     @Override