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.loxone.internal.types;
15 import java.util.Arrays;
16 import java.util.List;
17 import java.util.stream.Collectors;
19 import org.openhab.core.library.types.HSBType;
22 * Temperature HSB Type which acceptss a color in the form brigthness,temperature (Kelvin)
24 * @author Michael Mattan - initial contribution
27 public class LxTemperatureHSBType extends HSBType {
29 private static final long serialVersionUID = -2821122730407485795L;
31 public static HSBType fromBrightnessTemperature(String value) {
32 List<String> constituents = Arrays.stream(value.split(",")).map(in -> in.trim()).collect(Collectors.toList());
34 if (constituents.size() == 2) {
35 int brightness = constrain(Integer.valueOf(constituents.get(0)), 0, 100);
36 int temperature = constrain(Integer.valueOf(constituents.get(1)), 0, 65500);
38 int red = map(brightness, 0, 100, 0, calculateRed(temperature));
39 int green = map(brightness, 0, 100, 0, calculateGreen(temperature));
40 int blue = map(brightness, 0, 100, 0, calculateBlue(temperature));
42 return HSBType.fromRGB(red, green, blue);
44 throw new IllegalArgumentException(value + " is not a valid TemperatureHSBType syntax");
49 * Re-maps a number from one range to another. That is, a value of fromLow would get mapped to toLow, a value of
50 * fromHigh to toHigh, values in-between to values in-between, etc.
52 * @param x the number to map
53 * @param fromLow the lower bound of the value's current range
54 * @param fromHigh the upper bound of the value's current range
55 * @param toLow the lower bound of the value's target range
56 * @param toHigh the upper bound of the value's target range
57 * @return the mapped value
59 private static int map(int x, int fromLow, int fromHigh, int toLow, int toHigh) {
60 return (x - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
64 * calculates the red value based on the Kelvin temperature
66 * @param temp the Kelvin temperature
67 * @return the red value
69 private static int calculateRed(int temp) {
71 int temperature = temp / 100;
73 if (temperature > 66) {
74 red = temperature - 60;
75 red = ((Long) Math.round(329.698727466 * Math.pow(red, -0.1332047592))).intValue();
78 return constrain(red, 0, 255);
82 * calculates the green value based on the Kelvin temperature
84 * @param temp green Kelvin temperature
85 * @return the red value
87 private static int calculateGreen(int temp) {
89 int temperature = temp / 100;
91 if (temperature <= 66) {
93 green = ((Long) Math.round((99.4708025861 * Math.log(green)) - 161.1195681661)).intValue();
95 green = temperature - 60;
96 green = ((Long) Math.round(288.1221695283 * Math.pow(green, -0.0755148492))).intValue();
99 return constrain(green, 0, 255);
103 * calculates the blue value based on the Kelvin temperature
105 * @param temp the Kelvin temperature
106 * @return the blue value
108 private static int calculateBlue(int temp) {
110 int temperature = temp / 100;
112 if (temperature < 65) {
113 if (temperature <= 19) {
116 blue = temperature - 10;
117 blue = ((Long) Math.round((138.5177312231 * Math.log(blue)) - 305.0447927307)).intValue();
121 return constrain(blue, 0, 255);
125 * Constrains a number to be within a range.
127 * @param x the number to constrain
128 * @param min the minimum value
129 * @param max the maximum value
130 * @return the constrained value
132 private static int constrain(int x, int min, int max) {
133 if (x >= min && x <= max) {
135 } else if (x < min) {