| Channel | Type | Description |
|-|-|-|
-| `level` | Dimmer | Level changes the brightness of the globe. |
+| `level` | Dimmer | Level changes the brightness of the globe. Not present if the bulb supports the `colour` channel. |
| `colourTemperature` | Dimmer | Change from cool to warm white with this control. |
-| `colour` | Color | Allows you to change the colour, brightness and saturation of the globe. |
+| `colourTemperatureAbs` | Number:Temperature | Colour temperature in mireds. |
+| `colour` | Color | Allows you to change the colour, brightness and saturation of the globe. Can also be linked directly with a Dimmer item if you happen to have a bulb that doesn't support colour, but is controlled by a remote that normally does support colour. |
| `discoMode` | String | Switch to a Disco mode directly from a drop down list. |
| `bulbMode` | String (read only) | Displays the mode the bulb is currently in so that rules can determine if the globe is white, a color, disco modes or night mode are selected. |
| `command` | String | Sends the raw commands that the buttons on a remote send. |
*.items
```java
-Dimmer Hallway_Level "Front Hall" {channel="mqtt:rgb_cct:myBroker:0xE6C4:level"}
+Dimmer Hallway_Level "Front Hall" {channel="mqtt:rgb_cct:myBroker:0xE6C4:colour"}
Dimmer Hallway_ColourTemperature "White Color Temp" {channel="mqtt:rgb_cct:myBroker:0xE6C4:colourTemperature"}
+Number:Temperature Hallway_ColourTemperatureK "White Color Temp [%d %unit%]" {channel="mqtt:rgb_cct:myBroker:0xE6C4:colourTemperatureAbs", unit="K"}
Color Hallway_Colour "Front Hall" ["Lighting"] {channel="mqtt:rgb_cct:myBroker:0xE6C4:colour"}
String Hallway_DiscoMode "Disco Mode" {channel="mqtt:rgb_cct:myBroker:0xE6C4:discoMode"}
String Hallway_BulbCommand "Send Command" {channel="mqtt:rgb_cct:myBroker:0xE6C4:command"}
public static final String COMMANDS_BASE_TOPIC = "milight/commands/";
public static final String STATUS_TOPIC = "milight/status";
public static final BigDecimal BIG_DECIMAL_100 = new BigDecimal(100);
+ public static final BigDecimal BIG_DECIMAL_153 = new BigDecimal(153);
+ public static final BigDecimal BIG_DECIMAL_370 = new BigDecimal(370);
// List of all Thing Type UIDs
public static final ThingTypeUID THING_TYPE_RGB_CCT = new ThingTypeUID(BINDING_ID, "rgb_cct");
public static final ThingTypeUID THING_TYPE_CCT = new ThingTypeUID(BINDING_ID, "cct");
public static final String CHANNEL_LEVEL = "level";
public static final String CHANNEL_COLOUR = "colour";
public static final String CHANNEL_COLOURTEMP = "colourTemperature";
+ public static final String CHANNEL_COLOURTEMP_ABS = "colourTemperatureAbs";
public static final String CHANNEL_DISCO_MODE = "discoMode";
public static final String CHANNEL_BULB_MODE = "bulbMode";
public static final String CHANNEL_COMMAND = "command";
--- /dev/null
+/**
+ * Copyright (c) 2010-2023 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.mqtt.espmilighthub.internal;
+
+import static org.openhab.binding.mqtt.espmilighthub.internal.EspMilightHubBindingConstants.*;
+
+import java.math.BigDecimal;
+import java.util.Locale;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ThingRegistry;
+import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
+import org.openhab.core.types.StateDescription;
+import org.openhab.core.types.StateDescriptionFragmentBuilder;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides custom state descriptions for system.color-temperature-absolute channels.
+ *
+ * @author Cody Cutrer - Initial contribution
+ */
+@Component(service = DynamicStateDescriptionProvider.class)
+@NonNullByDefault
+public class EspMilightStateDescriptionProvider implements DynamicStateDescriptionProvider {
+ private final ThingRegistry thingRegistry;
+
+ @Activate
+ public EspMilightStateDescriptionProvider(@Reference ThingRegistry thingRegistry) {
+ this.thingRegistry = thingRegistry;
+ }
+
+ @Override
+ public @Nullable StateDescription getStateDescription(Channel channel, @Nullable StateDescription original,
+ @Nullable Locale locale) {
+ var logger = LoggerFactory.getLogger(EspMilightStateDescriptionProvider.class);
+ var channelUID = channel.getUID();
+ var thing = thingRegistry.get(channelUID.getThingUID());
+ if (thing == null || !SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())
+ || !channelUID.getId().equals(CHANNEL_COLOURTEMP_ABS)) {
+ return null;
+ }
+
+ StateDescriptionFragmentBuilder builder;
+ if (original != null) {
+ builder = StateDescriptionFragmentBuilder.create(original);
+ } else {
+ builder = StateDescriptionFragmentBuilder.create();
+ }
+ builder.withMinimum(BIG_DECIMAL_153).withMaximum(BIG_DECIMAL_370).withStep(BigDecimal.ONE)
+ .withPattern("%d mired");
+ return builder.build().toStateDescription();
+ }
+}
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
+import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
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());
String bulbLevel = Helper.resolveJSON(messageJSON, "\"level\":", 3);
if (!bulbLevel.isEmpty()) {
if ("0".equals(bulbLevel) || "OFF".equals(bulbState)) {
- changeChannel(CHANNEL_LEVEL, OnOffType.OFF);
+ if (!hasRGB()) {
+ changeChannel(CHANNEL_LEVEL, OnOffType.OFF);
+ }
} else {
tempBulbLevel = new PercentType(Integer.valueOf(bulbLevel));
- changeChannel(CHANNEL_LEVEL, tempBulbLevel);
+ savedLevel = tempBulbLevel.toBigDecimal();
+ if (!hasRGB()) {
+ 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));
+ if (!hasRGB()) {
+ changeChannel(CHANNEL_LEVEL, OnOffType.valueOf(bulbState));
+ }
}
bulbMode = Helper.resolveJSON(messageJSON, "\"bulb_mode\":\"", 5);
switch (bulbMode) {
if (!bulbCTempS.isEmpty()) {
var bulbCTemp = Integer.valueOf(bulbCTempS);
changeChannel(CHANNEL_COLOURTEMP, scaleMireds(bulbCTemp));
+ changeChannel(CHANNEL_COLOURTEMP_ABS, new QuantityType(bulbCTemp, Units.MIRED));
if (hasRGB()) {
changeChannel(CHANNEL_COLOUR, calculateHSBFromColorTemp(bulbCTemp, tempBulbLevel));
}
new PercentType(Integer.valueOf(bulbSaturation)), tempBulbLevel);
changeChannel(CHANNEL_COLOUR, hsb);
if (hasCCT()) {
- changeChannel(CHANNEL_COLOURTEMP, scaleMireds(calculateColorTempFromHSB(hsb)));
+ int mireds = calculateColorTempFromHSB(hsb);
+ changeChannel(CHANNEL_COLOURTEMP, scaleMireds(mireds));
+ changeChannel(CHANNEL_COLOURTEMP_ABS, new QuantityType(mireds, Units.MIRED));
}
}
break;
case "night":
if (hasRGB()) {
changeChannel(CHANNEL_BULB_MODE, new StringType("night"));
- if (config.oneTriggersNightMode) {
- changeChannel(CHANNEL_LEVEL, new PercentType("1"));
- }
}
break;
}
int scaledCommand = (int) Math.round((370 - (2.17 * Float.valueOf(command.toString()))));
sendMQTT("{\"state\":\"ON\",\"level\":" + savedLevel + ",\"color_temp\":" + scaledCommand + "}");
break;
+ case CHANNEL_COLOURTEMP_ABS:
+ int mireds;
+ QuantityType<?> miredsQt;
+ if (command instanceof QuantityType
+ && (miredsQt = ((QuantityType<?>) command).toInvertibleUnit(Units.MIRED)) != null) {
+ mireds = miredsQt.intValue();
+ } else {
+ mireds = Integer.valueOf(command.toString());
+ }
+ sendMQTT("{\"state\":\"ON\",\"level\":" + savedLevel + ",\"color_temp\":" + mireds + "}");
+ break;
case CHANNEL_COMMAND:
sendMQTT("{\"command\":\"" + command + "\"}");
break;
channel-type.mqtt.bulbMode.state.option.color = color
channel-type.mqtt.bulbMode.state.option.scene = scene
channel-type.mqtt.bulbMode.state.option.night = night
-channel-type.mqtt.colour.label = Colour
-channel-type.mqtt.colour.description = Allows you to change the colour, brightness and saturation of the globe.
-channel-type.mqtt.colourTemperature.label = Colour Temperature
-channel-type.mqtt.colourTemperature.description = Change from cool to warm white with this control.
channel-type.mqtt.command.label = Command
channel-type.mqtt.command.description = Send a raw command to the globe/s.
channel-type.mqtt.command.state.option.next_mode = Next Mode
channel-type.mqtt.discoMode.state.option.6 = Disco 6
channel-type.mqtt.discoMode.state.option.7 = Disco 7
channel-type.mqtt.discoMode.state.option.8 = Disco 8
-channel-type.mqtt.level.label = Level
-channel-type.mqtt.level.description = Level changes the brightness of the globe.
<description>LED globe with full Colour, and both cool and warm whites.</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colourTemperature" typeId="colourTemperature"/>
- <channel id="colour" typeId="colour"/>
+ <channel id="colourTemperature" typeId="system.color-temperature"/>
+ <channel id="colourTemperatureAbs" typeId="system.color-temperature-abs"/>
+ <channel id="colour" typeId="system.color"/>
<channel id="discoMode" typeId="discoMode"/>
<channel id="bulbMode" typeId="bulbMode"/>
<channel id="command" typeId="command"/>
<description>Use this when your remote is the newer 8 group type called FUT089 and your globes are rgb_cct</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colourTemperature" typeId="colourTemperature"/>
- <channel id="colour" typeId="colour"/>
+ <channel id="colourTemperature" typeId="system.color-temperature"/>
+ <channel id="colourTemperatureAbs" typeId="system.color-temperature-abs"/>
+ <channel id="colour" typeId="system.color"/>
<channel id="discoMode" typeId="discoMode"/>
<channel id="bulbMode" typeId="bulbMode"/>
<channel id="command" typeId="command"/>
<description>Use this when your remote is the newer fut091 and your globes are cct</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colourTemperature" typeId="colourTemperature"/>
+ <channel id="level" typeId="system.brightness"/>
+ <channel id="colourTemperature" typeId="system.color-temperature"/>
+ <channel id="colourTemperatureAbs" typeId="system.color-temperature-abs"/>
<channel id="command" typeId="command"/>
</channels>
<config-description-ref uri="thing-type:mqtt:cct"/>
<description>LED globe with both cool and warm white controls</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colourTemperature" typeId="colourTemperature"/>
+ <channel id="level" typeId="system.brightness"/>
+ <channel id="colourTemperature" typeId="system.color-temperature"/>
+ <channel id="colourTemperatureAbs" typeId="system.color-temperature-abs"/>
<channel id="command" typeId="command"/>
</channels>
<config-description-ref uri="thing-type:mqtt:cct"/>
<description>RGB Globe with a fixed white</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colour" typeId="colour"/>
+ <channel id="colour" typeId="system.color"/>
<channel id="discoMode" typeId="discoMode"/>
<channel id="bulbMode" typeId="bulbMode"/>
<channel id="command" typeId="command"/>
<description>RGB Globe with no white</description>
<category>Lightbulb</category>
<channels>
- <channel id="level" typeId="level"/>
- <channel id="colour" typeId="colour"/>
+ <channel id="colour" typeId="system.color"/>
<channel id="discoMode" typeId="discoMode"/>
<channel id="bulbMode" typeId="bulbMode"/>
<channel id="command" typeId="command"/>
<config-description-ref uri="thing-type:mqtt:rgb"/>
</thing-type>
- <channel-type id="level">
- <item-type>Dimmer</item-type>
- <label>Level</label>
- <description>Level changes the brightness of the globe.</description>
- <category>Slider</category>
- <tags>
- <tag>Control</tag>
- <tag>Light</tag>
- </tags>
- </channel-type>
-
- <channel-type id="colourTemperature">
- <item-type>Dimmer</item-type>
- <label>Colour Temperature</label>
- <description>Change from cool to warm white with this control.</description>
- <category>Slider</category>
- <tags>
- <tag>Control</tag>
- <tag>ColorTemperature</tag>
- </tags>
- </channel-type>
-
- <channel-type id="colour">
- <item-type>Color</item-type>
- <label>Colour</label>
- <description>Allows you to change the colour, brightness and saturation of the globe.</description>
- <category>ColorLight</category>
- <tags>
- <tag>Control</tag>
- <tag>Light</tag>
- </tags>
- </channel-type>
-
<channel-type id="command" advanced="true">
<item-type>String</item-type>
<label>Command</label>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+ xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+ <thing-type uid="mqtt:rgb_cct">
+ <instruction-set targetVersion="1">
+ <remove-channel id="level"/>
+ <update-channel id="colorTemperature">
+ <type>system:color-temperature</type>
+ </update-channel>
+ <add-channel id="colourTemperatureAbs">
+ <type>system:color-temperature-abs</type>
+ </add-channel>
+ <update-channel id="colour">
+ <type>system:color</type>
+ </update-channel>
+ </instruction-set>
+ </thing-type>
+
+ <thing-type uid="mqtt:fut089">
+ <instruction-set targetVersion="1">
+ <remove-channel id="level"/>
+ <update-channel id="colorTemperature">
+ <type>system:color-temperature</type>
+ </update-channel>
+ <add-channel id="colourTemperatureAbs">
+ <type>system:color-temperature-abs</type>
+ </add-channel>
+ <update-channel id="colour">
+ <type>system:color</type>
+ </update-channel>
+ </instruction-set>
+ </thing-type>
+
+ <thing-type uid="mqtt:fut091">
+ <instruction-set targetVersion="1">
+ <update-channel id="level">
+ <type>system:brightness</type>
+ </update-channel>
+ <update-channel id="colorTemperature">
+ <type>system:color-temperature</type>
+ </update-channel>
+ <add-channel id="colourTemperatureAbs">
+ <type>system:color-temperature-abs</type>
+ </add-channel>
+ </instruction-set>
+ </thing-type>
+
+ <thing-type uid="mqtt:cct">
+ <instruction-set targetVersion="1">
+ <update-channel id="level">
+ <type>system:brightness</type>
+ </update-channel>
+ <update-channel id="colorTemperature">
+ <type>system:color-temperature</type>
+ </update-channel>
+ <add-channel id="colourTemperatureAbs">
+ <type>system:color-temperature-abs</type>
+ </add-channel>
+ </instruction-set>
+ </thing-type>
+
+ <thing-type uid="mqtt:rgbw">
+ <instruction-set targetVersion="1">
+ <remove-channel id="level"/>
+ <update-channel id="colour">
+ <type>system:color</type>
+ </update-channel>
+ </instruction-set>
+ </thing-type>
+
+ <thing-type uid="mqtt:rgb">
+ <instruction-set targetVersion="1">
+ <remove-channel id="level"/>
+ <update-channel id="colour">
+ <type>system:color</type>
+ </update-channel>
+ </instruction-set>
+ </thing-type>
+
+</update:update-descriptions>