2 * Copyright (c) 2010-2023 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.lifx.internal.util;
15 import java.math.BigDecimal;
16 import java.math.RoundingMode;
17 import java.util.UUID;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.lifx.internal.LifxProduct.TemperatureRange;
21 import org.openhab.binding.lifx.internal.fields.HSBK;
22 import org.openhab.core.library.types.DecimalType;
23 import org.openhab.core.library.types.IncreaseDecreaseType;
24 import org.openhab.core.library.types.PercentType;
25 import org.openhab.core.library.types.QuantityType;
26 import org.openhab.core.library.unit.Units;
27 import org.openhab.core.types.Command;
30 * Utility class for sharing message utility methods between objects.
32 * @author Wouter Born - Initial contribution
35 public final class LifxMessageUtil {
37 private static final BigDecimal INCREASE_DECREASE_STEP = new BigDecimal(10);
39 private static final BigDecimal ZERO = PercentType.ZERO.toBigDecimal();
40 private static final BigDecimal HUNDRED = PercentType.HUNDRED.toBigDecimal();
42 private LifxMessageUtil() {
43 // hidden utility class constructor
46 public static PercentType increaseDecreasePercentType(IncreaseDecreaseType increaseDecreaseType, PercentType old) {
47 BigDecimal delta = ZERO;
48 if (increaseDecreaseType == IncreaseDecreaseType.INCREASE) {
49 delta = INCREASE_DECREASE_STEP;
50 } else if (increaseDecreaseType == IncreaseDecreaseType.DECREASE) {
51 delta = INCREASE_DECREASE_STEP.negate();
54 if (!ZERO.equals(delta)) {
55 BigDecimal newValue = old.toBigDecimal().add(delta);
56 newValue = newValue.setScale(0, RoundingMode.HALF_UP);
57 newValue = newValue.min(HUNDRED);
58 newValue = newValue.max(ZERO);
59 return new PercentType(newValue);
65 private static PercentType intToPercentType(int i) {
66 return new PercentType(Math.round((i / 65535.0f) * 100));
69 private static int percentTypeToInt(PercentType percentType) {
70 return (int) (percentType.floatValue() / 100 * 65535.0f);
73 public static DecimalType hueToDecimalType(int hue) {
74 return new DecimalType(hue * 360 / 65535.0f);
77 public static int decimalTypeToHue(DecimalType hue) {
78 return (int) (hue.floatValue() / 360 * 65535.0f);
81 public static PercentType saturationToPercentType(int saturation) {
82 return intToPercentType(saturation);
85 public static int percentTypeToSaturation(PercentType saturation) {
86 return percentTypeToInt(saturation);
89 public static PercentType brightnessToPercentType(int brightness) {
90 return intToPercentType(brightness);
93 public static int percentTypeToBrightness(PercentType brightness) {
94 return percentTypeToInt(brightness);
97 public static PercentType kelvinToPercentType(int kelvin, TemperatureRange temperatureRange) {
98 if (temperatureRange.getRange() == 0) {
99 return PercentType.HUNDRED;
101 BigDecimal value = BigDecimal
102 .valueOf((kelvin - temperatureRange.getMaximum()) / (temperatureRange.getRange() / -100));
103 value = value.min(HUNDRED);
104 value = value.max(ZERO);
105 return new PercentType(value);
108 public static int commandToKelvin(Command temperature, TemperatureRange temperatureRange) {
109 if (temperature instanceof PercentType percentValue) {
110 return percentTypeToKelvin(percentValue, temperatureRange);
111 } else if (temperature instanceof QuantityType quantityValue) {
112 return quantityTypeToKelvin(quantityValue, temperatureRange);
113 } else if (temperature instanceof DecimalType decimalValue) {
114 return decimalTypeToKelvin(decimalValue, temperatureRange);
116 throw new IllegalStateException(
117 "Unexpected command type " + temperature.getClass().getName() + " for color temperature command.");
121 public static int decimalTypeToKelvin(DecimalType temperature, TemperatureRange temperatureRange) {
122 return Math.round(Math.min(Math.max(temperature.intValue(), temperatureRange.getMinimum()),
123 temperatureRange.getMaximum()));
126 public static int percentTypeToKelvin(PercentType temperature, TemperatureRange temperatureRange) {
128 temperatureRange.getMaximum() - (temperature.floatValue() * (temperatureRange.getRange() / 100)));
131 public static int quantityTypeToKelvin(QuantityType temperature, TemperatureRange temperatureRange) {
132 QuantityType<?> asKelvin = temperature.toInvertibleUnit(Units.KELVIN);
133 if (asKelvin == null) {
134 throw new IllegalStateException(
135 "Cannot convert color temperature " + temperature.toString() + " to Kelvin");
138 return asKelvin.intValue();
141 public static PercentType infraredToPercentType(int infrared) {
142 return intToPercentType(infrared);
145 public static int percentTypeToInfrared(PercentType infrared) {
146 return percentTypeToInt(infrared);
149 public static boolean sameColors(HSBK... colors) {
150 if (colors.length <= 1) {
154 for (int i = 1; i < colors.length; i++) {
155 if (!colors[0].equals(colors[i])) {
162 public static long randomSourceId() {
163 return UUID.randomUUID().getLeastSignificantBits() & (-1L >>> 32);