From 6bdcd15d9963479ff2afe6dc5806dd5c90523c2e Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Mon, 28 Nov 2022 16:33:49 -0700 Subject: [PATCH] [mqtt.espmilight] Automatically convert color values to color temp (#13578) * [mqtt.espmilight] Automatically convert color values to color temp for RGB+CCT bulbs Yes, it's lots of math, but references are provided. This supplants whiteThreshold for RGB+CCT bulbs since it is far more flexible and accurate. Signed-off-by: Cody Cutrer --- .../README.md | 1 + .../espmilighthub/internal/ConfigOptions.java | 7 +- .../handler/EspMilightHubHandler.java | 208 ++++++++++++++++-- .../main/resources/OH-INF/config/config.xml | 24 +- .../resources/OH-INF/i18n/mqtt.properties | 14 +- .../resources/OH-INF/thing/thing-types.xml | 4 +- 6 files changed, 216 insertions(+), 42 deletions(-) diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/README.md b/bundles/org.openhab.binding.mqtt.espmilighthub/README.md index 2928a7db0..7de8c6c8b 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/README.md +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/README.md @@ -106,6 +106,7 @@ Note that the group 0 (or ALL group) is not auto discovered as a thing and thus | `oneTriggersNightMode` | Night mode is a much lower level of light and this feature allows it to be auto selected when your fader/slider moves to 1%. NOTE: Night mode by design locks out some controls of a physical remote, so this feature is disabled by default. | Y | false | | `powerFailsToMinimum` | If lights loose power from the power switch OR a power outage, they will default to using the lowest brightness if the light was turned off before the power failure occurred. | Y | true | | `whiteThreshold` | This feature allows you to use a color control to change to using the real white LEDs when the saturation is equal to, or below this threshold. -1 will disable this feature. | Y | 12 | +| `duvThreshold` | This feature allows you to use a color control to change to using the real warm/cool white LEDs to set a white color temperature if the color is within a certain threshold of the block body curve. 1 will effectively disable this feature. The default settings maps well to Apple's HomeKit that will allow you to choose a color temperature, but sends it as an HSB value. See https://www.waveformlighting.com/tech/calculate-duv-from-cie-1931-xy-coordinates/ for more information. | Y | 0.003 | ## Channels diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/ConfigOptions.java b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/ConfigOptions.java index 1364b7d9a..878279b25 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/ConfigOptions.java +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/ConfigOptions.java @@ -12,6 +12,8 @@ */ package org.openhab.binding.mqtt.espmilighthub.internal; +import java.math.BigDecimal; + import org.eclipse.jdt.annotation.NonNullByDefault; /** @@ -21,9 +23,10 @@ import org.eclipse.jdt.annotation.NonNullByDefault; */ @NonNullByDefault public class ConfigOptions { + public BigDecimal duvThreshold = new BigDecimal("0.003"); public int whiteThreshold = -1; - public int whiteSat = 32; - public int whiteHue = 35; + public int whiteSat = -1; + public int whiteHue = -1; public int favouriteWhite = 200; public boolean oneTriggersNightMode = false; public boolean powerFailsToMinimum = false; diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/handler/EspMilightHubHandler.java b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/handler/EspMilightHubHandler.java index e4f2186ba..e505a9d83 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/handler/EspMilightHubHandler.java +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/handler/EspMilightHubHandler.java @@ -17,6 +17,7 @@ import static org.openhab.binding.mqtt.MqttBindingConstants.BINDING_ID; import static org.openhab.binding.mqtt.espmilighthub.internal.EspMilightHubBindingConstants.*; import java.math.BigDecimal; +import java.math.MathContext; import java.nio.charset.StandardCharsets; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -28,6 +29,7 @@ import org.openhab.core.io.transport.mqtt.MqttBrokerConnection; import org.openhab.core.io.transport.mqtt.MqttConnectionObserver; import org.openhab.core.io.transport.mqtt.MqttConnectionState; import org.openhab.core.io.transport.mqtt.MqttMessageSubscriber; +import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.HSBType; import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; @@ -56,6 +58,46 @@ import org.slf4j.LoggerFactory; */ @NonNullByDefault public class EspMilightHubHandler extends BaseThingHandler implements MqttConnectionObserver, MqttMessageSubscriber { + // these are all constants used in color conversion calcuations. + // strings are necessary to prevent floating point loss of precision + private static final BigDecimal BIG_DECIMAL_THOUSAND = new BigDecimal(1000); + private static final BigDecimal BIG_DECIMAL_MILLION = new BigDecimal(1000000); + + private static final BigDecimal[][] KANG_X_COEFFICIENTS = { + { new BigDecimal("-3.0258469"), new BigDecimal("2.1070379"), new BigDecimal("0.2226347"), + new BigDecimal("0.24039") }, + { new BigDecimal("-0.2661239"), new BigDecimal("-0.234589"), new BigDecimal("0.8776956"), + new BigDecimal("0.179910") } }; + + private static final BigDecimal[][] KANG_Y_COEFFICIENTS = { + { new BigDecimal("3.0817580"), new BigDecimal("-5.8733867"), new BigDecimal("3.75112997"), + new BigDecimal("-0.37001483") }, + { new BigDecimal("-0.9549476"), new BigDecimal("-1.37418593"), new BigDecimal("2.09137015"), + new BigDecimal("-0.16748867") }, + { new BigDecimal("-1.1063814"), new BigDecimal("-1.34811020"), new BigDecimal("2.18555832"), + new BigDecimal("-0.20219683") } }; + + private static final BigDecimal BIG_DECIMAL_03320 = new BigDecimal("0.3320"); + private static final BigDecimal BIG_DECIMAL_01858 = new BigDecimal("0.1858"); + private static final BigDecimal[] MCCAMY_COEFFICIENTS = { new BigDecimal(437), new BigDecimal(3601), + new BigDecimal(6862), new BigDecimal(5517) }; + + private static final BigDecimal BIG_DECIMAL_2 = new BigDecimal(2); + private static final BigDecimal BIG_DECIMAL_3 = new BigDecimal(3); + private static final BigDecimal BIG_DECIMAL_4 = new BigDecimal(4); + private static final BigDecimal BIG_DECIMAL_6 = new BigDecimal(6); + private static final BigDecimal BIG_DECIMAL_12 = new BigDecimal(12); + + private static final BigDecimal BIG_DECIMAL_0292 = new BigDecimal("0.292"); + private static final BigDecimal BIG_DECIMAL_024 = new BigDecimal("0.24"); + + private static final BigDecimal[] CORM_COEFFICIENTS = { new BigDecimal("-0.00616793"), new BigDecimal("0.0893944"), + new BigDecimal("-0.5179722"), new BigDecimal("1.5317403"), new BigDecimal("-2.4243787"), + new BigDecimal("1.925865"), new BigDecimal("-0.471106") }; + + private static final BigDecimal BIG_DECIMAL_153 = new BigDecimal(153); + private static final BigDecimal BIG_DECIMAL_217 = new BigDecimal(217); + private final Logger logger = LoggerFactory.getLogger(this.getClass()); private @Nullable MqttBrokerConnection connection; private ThingRegistry thingRegistry; @@ -106,16 +148,15 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec private void processIncomingState(String messageJSON) { // Need to handle State and Level at the same time to process level=0 as off// - BigDecimal tempBulbLevel = BigDecimal.ZERO; + PercentType tempBulbLevel = PercentType.ZERO; String bulbState = Helper.resolveJSON(messageJSON, "\"state\":\"", 3); String bulbLevel = Helper.resolveJSON(messageJSON, "\"level\":", 3); if (!bulbLevel.isEmpty()) { if ("0".equals(bulbLevel) || "OFF".equals(bulbState)) { changeChannel(CHANNEL_LEVEL, OnOffType.OFF); - tempBulbLevel = BigDecimal.ZERO; } else { - tempBulbLevel = new BigDecimal(bulbLevel); - changeChannel(CHANNEL_LEVEL, new PercentType(tempBulbLevel)); + tempBulbLevel = new PercentType(Integer.valueOf(bulbLevel)); + changeChannel(CHANNEL_LEVEL, tempBulbLevel); } } else if ("ON".equals(bulbState) || "OFF".equals(bulbState)) { // NOTE: Level is missing when this runs changeChannel(CHANNEL_LEVEL, OnOffType.valueOf(bulbState)); @@ -123,15 +164,17 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec bulbMode = Helper.resolveJSON(messageJSON, "\"bulb_mode\":\"", 5); switch (bulbMode) { case "white": - if (!"cct".equals(globeType) && !"fut091".equals(globeType)) { + if (hasRGB()) { changeChannel(CHANNEL_BULB_MODE, new StringType("white")); - changeChannel(CHANNEL_COLOUR, new HSBType("0,0," + tempBulbLevel)); changeChannel(CHANNEL_DISCO_MODE, new StringType("None")); } - String bulbCTemp = Helper.resolveJSON(messageJSON, "\"color_temp\":", 3); - if (!bulbCTemp.isEmpty()) { - int ibulbCTemp = (int) Math.round(((Float.valueOf(bulbCTemp) / 2.17) - 171) * -1); - changeChannel(CHANNEL_COLOURTEMP, new PercentType(ibulbCTemp)); + String bulbCTempS = Helper.resolveJSON(messageJSON, "\"color_temp\":", 3); + if (!bulbCTempS.isEmpty()) { + var bulbCTemp = Integer.valueOf(bulbCTempS); + changeChannel(CHANNEL_COLOURTEMP, scaleMireds(bulbCTemp)); + if (hasRGB()) { + changeChannel(CHANNEL_COLOUR, calculateHSBFromColorTemp(bulbCTemp, tempBulbLevel)); + } } break; case "color": @@ -145,11 +188,20 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec if (bulbSaturation.isEmpty()) { bulbSaturation = "100"; } - changeChannel(CHANNEL_COLOUR, new HSBType(bulbHue + "," + bulbSaturation + "," + tempBulbLevel)); + // 360 isn't allowed by OpenHAB + if (bulbHue.equals("360")) { + bulbHue = "0"; + } + var hsb = new HSBType(new DecimalType(Integer.valueOf(bulbHue)), + new PercentType(Integer.valueOf(bulbSaturation)), tempBulbLevel); + changeChannel(CHANNEL_COLOUR, hsb); + if (hasCCT()) { + changeChannel(CHANNEL_COLOURTEMP, scaleMireds(calculateColorTempFromHSB(hsb))); + } } break; case "scene": - if (!"cct".equals(globeType) && !"fut091".equals(globeType)) { + if (hasRGB()) { changeChannel(CHANNEL_BULB_MODE, new StringType("scene")); } String bulbDiscoMode = Helper.resolveJSON(messageJSON, "\"mode\":", 1); @@ -158,7 +210,7 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec } break; case "night": - if (!"cct".equals(globeType) && !"fut091".equals(globeType)) { + if (hasRGB()) { changeChannel(CHANNEL_BULB_MODE, new StringType("night")); if (config.oneTriggersNightMode) { changeChannel(CHANNEL_LEVEL, new PercentType("1")); @@ -168,6 +220,113 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec } } + private boolean hasCCT() { + switch (globeType) { + case "rgb_cct": + case "cct": + case "fut089": + case "fut091": + return true; + default: + return false; + } + } + + private boolean hasRGB() { + switch (globeType) { + case "rgb_cct": + case "rgb": + case "rgbw": + case "fut089": + return true; + default: + return false; + } + } + + /** + * Scales mireds to 0-100% + */ + private static PercentType scaleMireds(int mireds) { + // range in mireds is 153-370 + // 100 - (mireds - 153) / (370 - 153) * 100 + if (mireds >= 370) { + return PercentType.HUNDRED; + } else if (mireds <= 153) { + return PercentType.ZERO; + } + return new PercentType(BIG_DECIMAL_100.subtract(new BigDecimal(mireds).subtract(BIG_DECIMAL_153) + .divide(BIG_DECIMAL_217, MathContext.DECIMAL128).multiply(BIG_DECIMAL_100))); + } + + private static BigDecimal polynomialFit(BigDecimal x, BigDecimal[] coefficients) { + var result = BigDecimal.ZERO; + var xAccumulator = BigDecimal.ONE; + // forms K[4]*x^0 + K[3]*x^1 + K[2]*x^2 + K[1]*x^3 + K[0]*x^4 + // (or reverse the order of terms for the usual way of writing it in academic papers) + for (int i = coefficients.length - 1; i >= 0; i--) { + result = result.add(coefficients[i].multiply(xAccumulator)); + xAccumulator = xAccumulator.multiply(x); + } + return result; + } + + // https://www.jkps.or.kr/journal/download_pdf.php?spage=865&volume=41&number=6 (8) and (9) + private static HSBType calculateHSBFromColorTemp(int mireds, PercentType brightness) { + var cct = BIG_DECIMAL_MILLION.divide(new BigDecimal(mireds), MathContext.DECIMAL128); + var cctInt = cct.intValue(); + + BigDecimal[] coefficients; + // 1667K to 4000K and 4000K to 25000K; no range checks since our mired range fits within this + if (cctInt <= 4000) { + coefficients = KANG_X_COEFFICIENTS[1]; + } else { + coefficients = KANG_X_COEFFICIENTS[0]; + } + BigDecimal x = polynomialFit(BIG_DECIMAL_THOUSAND.divide(cct, MathContext.DECIMAL128), coefficients); + + if (cctInt <= 2222) { + coefficients = KANG_Y_COEFFICIENTS[2]; + } else if (cctInt <= 4000) { + coefficients = KANG_Y_COEFFICIENTS[1]; + } else { + coefficients = KANG_Y_COEFFICIENTS[0]; + } + BigDecimal y = polynomialFit(x, coefficients); + var rawHsb = HSBType.fromXY(x.floatValue() * 100.0f, y.floatValue() * 100.0f); + return new HSBType(rawHsb.getHue(), rawHsb.getSaturation(), brightness); + } + + // https://www.waveformlighting.com/tech/calculate-color-temperature-cct-from-cie-1931-xy-coordinates/ + private static int calculateColorTempFromHSB(HSBType hsb) { + PercentType[] xy = hsb.toXY(); + var x = xy[0].toBigDecimal().divide(BIG_DECIMAL_100); + var y = xy[1].toBigDecimal().divide(BIG_DECIMAL_100); + var n = x.subtract(BIG_DECIMAL_03320).divide(BIG_DECIMAL_01858.subtract(y), MathContext.DECIMAL128); + BigDecimal cctK = polynomialFit(n, MCCAMY_COEFFICIENTS); + return BIG_DECIMAL_MILLION.divide(cctK, MathContext.DECIMAL128).round(new MathContext(0)).intValue(); + } + + // https://cormusa.org/wp-content/uploads/2018/04/CORM_2011_Calculation_of_CCT_and_Duv_and_Practical_Conversion_Formulae.pdf + // page 19 + private static BigDecimal calculateDuvFromHSB(HSBType hsb) { + PercentType[] xy = hsb.toXY(); + var x = xy[0].toBigDecimal().divide(BIG_DECIMAL_100); + var y = xy[1].toBigDecimal().divide(BIG_DECIMAL_100); + var u = BIG_DECIMAL_4.multiply(x).divide( + BIG_DECIMAL_2.multiply(x).negate().add(BIG_DECIMAL_12.multiply(y).add(BIG_DECIMAL_3)), + MathContext.DECIMAL128); + var v = BIG_DECIMAL_6.multiply(y).divide( + BIG_DECIMAL_2.multiply(x).negate().add(BIG_DECIMAL_12.multiply(y).add(BIG_DECIMAL_3)), + MathContext.DECIMAL128); + var Lfp = u.subtract(BIG_DECIMAL_0292).pow(2).add(v.subtract(BIG_DECIMAL_024).pow(2)) + .sqrt(MathContext.DECIMAL128); + var a = new BigDecimal( + Math.acos(u.subtract(BIG_DECIMAL_0292).divide(Lfp, MathContext.DECIMAL128).doubleValue())); + BigDecimal Lbb = polynomialFit(a, CORM_COEFFICIENTS); + return Lfp.subtract(Lbb); + } + /* * Used to calculate the colour temp for a globe if you want the light to get warmer as it is dimmed like a * traditional halogen globe @@ -187,6 +346,8 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec } void handleLevelColour(Command command) { + int mireds; + if (command instanceof OnOffType) { if (OnOffType.ON.equals(command)) { sendMQTT("{\"state\":\"ON\",\"level\":" + savedLevel + "}"); @@ -210,7 +371,7 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec HSBType hsb = (HSBType) command; // This feature allows google home or Echo to trigger white mode when asked to turn color to white. if (hsb.getHue().intValue() == config.whiteHue && hsb.getSaturation().intValue() == config.whiteSat) { - if ("rgb_cct".equals(globeType) || "fut089".equals(globeType)) { + if (hasCCT()) { sendMQTT("{\"state\":\"ON\",\"color_temp\":" + config.favouriteWhite + "}"); } else {// globe must only have 1 type of white sendMQTT("{\"command\":\"set_white\"}"); @@ -219,6 +380,10 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec } else if (PercentType.ZERO.equals(hsb.getBrightness())) { turnOff(); return; + } else if (config.duvThreshold.compareTo(BigDecimal.ONE) < 0 + && calculateDuvFromHSB(hsb).abs().compareTo(config.duvThreshold) <= 0 + && (mireds = calculateColorTempFromHSB(hsb)) >= 153 && mireds <= 370) { + sendMQTT("{\"state\":\"ON\",\"level\":" + hsb.getBrightness() + ",\"color_temp\":" + mireds + "}"); } else if (config.whiteThreshold != -1 && hsb.getSaturation().intValue() <= config.whiteThreshold) { sendMQTT("{\"command\":\"set_white\"}");// Can't send the command and level in the same message. sendMQTT("{\"level\":" + hsb.getBrightness().intValue() + "}"); @@ -239,7 +404,7 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec } sendMQTT("{\"state\":\"ON\",\"level\":" + command + "}"); savedLevel = percentType.toBigDecimal(); - if ("rgb_cct".equals(globeType) || "fut089".equals(globeType)) { + if (hasCCT()) { if (config.dimmedCT > 0 && "white".equals(bulbMode)) { sendMQTT("{\"state\":\"ON\",\"color_temp\":" + autoColourTemp(savedLevel.intValue()) + "}"); } @@ -254,9 +419,10 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec return; } switch (channelUID.getId()) { + case CHANNEL_COLOUR: case CHANNEL_LEVEL: handleLevelColour(command); - return; + break; case CHANNEL_BULB_MODE: bulbMode = command.toString(); break; @@ -270,8 +436,6 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec case CHANNEL_DISCO_MODE: sendMQTT("{\"mode\":\"" + command + "\"}"); break; - case CHANNEL_COLOUR: - handleLevelColour(command); } } @@ -322,8 +486,12 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec @Override public void processMessage(String topic, byte[] payload) { String state = new String(payload, StandardCharsets.UTF_8); - logger.trace("Recieved the following new Milight state:{}:{}", topic, state); - processIncomingState(state); + logger.trace("Received the following new Milight state:{}:{}", topic, state); + try { + processIncomingState(state); + } catch (Exception e) { + logger.warn("Failed processing Milight state {} for {}", state, topic, e); + } } @Override diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/config/config.xml index f6cf7d88e..6a809ff12 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/config/config.xml @@ -13,7 +13,7 @@ - If lights loose power when soft off, the lights will default back to the minimum brightness. + If lights lose power when soft off, the lights will default back to the minimum brightness. false @@ -37,23 +37,25 @@ When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. - 35 + -1 When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. - 32 + -1 - - - Saturation values at or below this value on a RGBW color control will trigger the white mode. -1 will - disable - this feature. + + + this link for more information on how this is calculated. + ]]> - 6 + 0.003 @@ -76,7 +78,7 @@ - If lights loose power, the lights will turn on to the minimum brightness. + If lights lose power, the lights will turn on to the minimum brightness. true @@ -104,7 +106,7 @@ - If lights loose power, the lights will turn on to the minimum brightness. + If lights lose power, the lights will turn on to the minimum brightness. false diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/i18n/mqtt.properties b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/i18n/mqtt.properties index 555b7126c..6b5bd216c 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/i18n/mqtt.properties +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/i18n/mqtt.properties @@ -1,7 +1,7 @@ # thing types thing-type.mqtt.cct.label = Milight CCT -thing-type.mqtt.cct.description = Led globe with both cool and warm white controls +thing-type.mqtt.cct.description = LED globe with both cool and warm white controls thing-type.mqtt.fut089.label = Milight FUT089 thing-type.mqtt.fut089.description = Use this when your remote is the newer 8 group type called FUT089 and your globes are rgb_cct thing-type.mqtt.fut091.label = Milight FUT091 @@ -9,7 +9,7 @@ thing-type.mqtt.fut091.description = Use this when your remote is the newer fut0 thing-type.mqtt.rgb.label = Milight RGB thing-type.mqtt.rgb.description = RGB Globe with no white thing-type.mqtt.rgb_cct.label = Milight RGBCCT -thing-type.mqtt.rgb_cct.description = Led globe with full Colour, and both cool and warm whites. +thing-type.mqtt.rgb_cct.description = LED globe with full Colour, and both cool and warm whites. thing-type.mqtt.rgbw.label = Milight RGBW thing-type.mqtt.rgbw.description = RGB Globe with a fixed white @@ -22,25 +22,25 @@ thing-type.config.mqtt.cct.oneTriggersNightMode.description = 1% on a slider wil thing-type.config.mqtt.rgb.oneTriggersNightMode.label = 1% Triggers Night Mode thing-type.config.mqtt.rgb.oneTriggersNightMode.description = 1% on a slider will trigger the Night Mode. thing-type.config.mqtt.rgb.powerFailsToMinimum.label = Dimmed on Power Fail -thing-type.config.mqtt.rgb.powerFailsToMinimum.description = If lights loose power when soft off, the lights will default back to the minimum brightness. +thing-type.config.mqtt.rgb.powerFailsToMinimum.description = If lights lose power when soft off, the lights will default back to the minimum brightness. thing-type.config.mqtt.rgbandcct.dimmedCT.label = Dimmed Colour Temp thing-type.config.mqtt.rgbandcct.dimmedCT.description = Traditional globes grow warmer the more they are dimmed. Set this to 370, or leave blank to disable. +thing-type.config.mqtt.rgbandcct.duvThreshold.label = Duv Threshold +thing-type.config.mqtt.rgbandcct.duvThreshold.description = Duv values at or below this value on a RGBWW color control will trigger white mode at the appropriate color temperature. 1 will effectively disable this feature. See this link for more information on how this is calculated. thing-type.config.mqtt.rgbandcct.favouriteWhite.label = Favourite White thing-type.config.mqtt.rgbandcct.favouriteWhite.description = When a shortcut triggers white mode, use this for the colour white. thing-type.config.mqtt.rgbandcct.oneTriggersNightMode.label = 1% Triggers Night Mode thing-type.config.mqtt.rgbandcct.oneTriggersNightMode.description = 1% on a slider will trigger the Night Mode. thing-type.config.mqtt.rgbandcct.powerFailsToMinimum.label = Dimmed on Power Fail -thing-type.config.mqtt.rgbandcct.powerFailsToMinimum.description = If lights loose power, the lights will turn on to the minimum brightness. +thing-type.config.mqtt.rgbandcct.powerFailsToMinimum.description = If lights lose power, the lights will turn on to the minimum brightness. thing-type.config.mqtt.rgbandcct.whiteHue.label = White Hue thing-type.config.mqtt.rgbandcct.whiteHue.description = When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. thing-type.config.mqtt.rgbandcct.whiteSat.label = White Saturation thing-type.config.mqtt.rgbandcct.whiteSat.description = When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. -thing-type.config.mqtt.rgbandcct.whiteThreshold.label = White Threshold -thing-type.config.mqtt.rgbandcct.whiteThreshold.description = Saturation values at or below this value on a RGBW color control will trigger the white mode. -1 will disable this feature. thing-type.config.mqtt.rgbw.oneTriggersNightMode.label = 1% Triggers Night Mode thing-type.config.mqtt.rgbw.oneTriggersNightMode.description = 1% on a slider will trigger the Night Mode. thing-type.config.mqtt.rgbw.powerFailsToMinimum.label = Dimmed on Power Fail -thing-type.config.mqtt.rgbw.powerFailsToMinimum.description = If lights loose power, the lights will turn on to the minimum brightness. +thing-type.config.mqtt.rgbw.powerFailsToMinimum.description = If lights lose power, the lights will turn on to the minimum brightness. thing-type.config.mqtt.rgbw.whiteHue.label = White Hue thing-type.config.mqtt.rgbw.whiteHue.description = When both the whiteHue and whiteSat values are seen by the binding it will trigger the white LEDS. thing-type.config.mqtt.rgbw.whiteSat.label = White Saturation diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/thing/thing-types.xml index 14fd4892b..165320bb1 100644 --- a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/thing/thing-types.xml @@ -9,7 +9,7 @@ - Led globe with full Colour, and both cool and warm whites. + LED globe with full Colour, and both cool and warm whites. Lightbulb @@ -60,7 +60,7 @@ - Led globe with both cool and warm white controls + LED globe with both cool and warm white controls Lightbulb