/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.ecobee.messages; import java.math.BigDecimal; import java.math.MathContext; import org.codehaus.jackson.annotate.JsonCreator; import org.codehaus.jackson.annotate.JsonValue; /** * Temperature values are expressed as degrees Fahrenheit, multiplied by 10. For example, a temperature of 72F would be * expressed as the value 720. If the user preferences indicate the use of Celsius values, it is the responsibility of * the caller to convert values to and from Celsius. * * <p> * Where specified explicitly Degrees F indicates that the temperature will be returned in degrees Fahrenheit accurate * to one decimal place (i.e. 18.5F). * * <p> * Methods are included to construct Temperature objects from Celsius, Fahrenheit, or whichever the local temperature * scale is. * * @see <a href="https://www.ecobee.com/home/developer/api/documentation/v1/technical-notes.shtml#representation">Values * and Representation</a> * @author John Cocula * @since 1.7.0 */ public class Temperature { /** * Enum for representing the temperature scale that will be reported. */ public static enum Scale { CELSIUS("C"), FAHRENHEIT("F"); private final String scale; private Scale(final String scale) { this.scale = scale; } public String value() { return scale; } public static Scale forValue(String v) { for (Scale s : Scale.values()) { if (s.scale.equals(v)) { return s; } } throw new IllegalArgumentException("Invalid temperature scale: " + v); } } /** * The local temperature scale used throughout this JVM. Defaults to Fahrenheit. */ private static Scale localScale = Scale.FAHRENHEIT; public static void setLocalScale(final Scale localScale) { Temperature.localScale = localScale; } private BigDecimal temp; @JsonValue public int value() { return temp.intValue(); } /** * Construct a Temperature from the Ecobee-style temperature value (Fahrenheit times 10). * * @param temp * Ecobee-style temperature value (Fahrenheit times 10) */ @JsonCreator public Temperature(int temp) { this.temp = new BigDecimal(temp); } /** * Construct a Temperature from the Ecobee-style temperature value (Fahrenheit times 10). * * @param temp * Ecobee-style temperature value (Fahrenheit times 10) */ public Temperature(BigDecimal temp) { this.temp = temp; } /** * Factory method to construct a Temperature from the local temperature scale. * * @param localTemp * the temperature in the local temperature scale. * @return a new Temperature object */ public static Temperature fromLocalTemperature(BigDecimal localTemp) { if (localScale.equals(Scale.CELSIUS)) { return fromCelsius(localTemp); } else { return fromFahrenheit(localTemp); } } /** * Factory method to construct a Temperature from Fahrenheit. * * @param fahrenheit * the Fahrenheit temperature */ public static Temperature fromFahrenheit(BigDecimal fahrenheit) { return new Temperature(fahrenheit.movePointRight(1)); } private static BigDecimal ONE_POINT_EIGHT = new BigDecimal("1.8"); private static BigDecimal THIRTY_TWO = new BigDecimal("32"); /** * Factory method to construct a Temperature from Celsius. * * @param celsius * the Celsius temperature */ public static Temperature fromCelsius(BigDecimal celsius) { return new Temperature(celsius.multiply(ONE_POINT_EIGHT).add(THIRTY_TWO).movePointRight(1)); } /** * Convert this temperature to a temperature in the local temperature scale. * * @return temperature in the local temperature scale */ public final BigDecimal toLocalTemperature() { return localScale == Scale.CELSIUS ? toCelsius() : toFahrenheit(); } /** * Convert this Temperature to Fahrenheit. * * @return temperature in Fahrenheit */ public final BigDecimal toFahrenheit() { return temp.movePointLeft(1); } /** * Convert this Temperature to Celsius. * * @return temperature in Celsius */ public final BigDecimal toCelsius() { return temp.movePointLeft(1).subtract(THIRTY_TWO).divide(ONE_POINT_EIGHT, MathContext.DECIMAL32); } @Override public String toString() { return temp.toString(); } }