]> git.basschouten.com Git - openhab-addons.git/commitdiff
[mqtt.espmilighthub] Use system channel types for color temp and brightness (#13801)
authorCody Cutrer <cody@cutrer.us>
Sat, 16 Dec 2023 08:49:35 +0000 (01:49 -0700)
committerGitHub <noreply@github.com>
Sat, 16 Dec 2023 08:49:35 +0000 (09:49 +0100)
* [mqtt.espmilighthub] use system channel types for color temp and brightness

closes #10096

also add absolute color temp channel. and remove level channel when we
already have a color channel (you can link a DimmerItem to a color
channel if your light doesn't happen to have color or you want direct
control of brightness only for some reason)

---------

Signed-off-by: Cody Cutrer <cody@cutrer.us>
bundles/org.openhab.binding.mqtt.espmilighthub/README.md
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/EspMilightHubBindingConstants.java
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/EspMilightStateDescriptionProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/handler/EspMilightHubHandler.java
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/i18n/mqtt.properties
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/update/instructions.xml [new file with mode: 0644]

index 1a4e5587b02ed0ad0b21f728b31e70ee8be7d5cd..b17a35670ecac58e9a8691e92675f14bfdf79b4c 100644 (file)
@@ -118,9 +118,10 @@ Note that the group 0 (or ALL group) is not auto discovered as a thing and thus
 
 | 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. |
@@ -192,8 +193,9 @@ Thing mqtt:rgb_cct:myBroker:0xE6C4 "Hallway" (mqtt:broker:myBroker) @ "MQTT"
 *.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"}
index bd5bf8c73e349285fa6f1a9b404b62144dc9fd4c..2f538b7600e886da16cda5567c449a596b71b736 100644 (file)
@@ -33,6 +33,8 @@ public class EspMilightHubBindingConstants {
     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");
@@ -48,6 +50,7 @@ public class EspMilightHubBindingConstants {
     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";
diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/EspMilightStateDescriptionProvider.java b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/java/org/openhab/binding/mqtt/espmilighthub/internal/EspMilightStateDescriptionProvider.java
new file mode 100644 (file)
index 0000000..a03a5d6
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * 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();
+    }
+}
index cfc64a3877ea15036313b7d3446215a557f60104..58c1712abbe6f938501c29fc465892633a47a51d 100644 (file)
@@ -35,7 +35,9 @@ import org.openhab.core.library.types.HSBType;
 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;
@@ -97,7 +99,6 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
             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());
@@ -155,13 +156,20 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
         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) {
@@ -174,6 +182,7 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
                 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));
                     }
@@ -198,7 +207,9 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
                             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;
@@ -214,9 +225,6 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
             case "night":
                 if (hasRGB()) {
                     changeChannel(CHANNEL_BULB_MODE, new StringType("night"));
-                    if (config.oneTriggersNightMode) {
-                        changeChannel(CHANNEL_LEVEL, new PercentType("1"));
-                    }
                 }
                 break;
         }
@@ -430,6 +438,17 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttMessag
                 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;
index 6b5bd216cfb145fd84416e14e5c3a12300dd0b31..ebbdcb677916551310528beb7e5ff58ca79baf70 100644 (file)
@@ -56,10 +56,6 @@ channel-type.mqtt.bulbMode.state.option.white = white
 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
@@ -83,5 +79,3 @@ channel-type.mqtt.discoMode.state.option.5 = Disco 5
 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.
index 165320bb1edfd9b3843cc67718b2cfc9bcef3b26..3ca8031feaaa9fc2d5e5d622c194e6d60987f9f4 100644 (file)
@@ -12,9 +12,9 @@
                <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"/>
@@ -30,9 +30,9 @@
                <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"/>
@@ -48,8 +48,9 @@
                <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"/>
@@ -63,8 +64,9 @@
                <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"/>
@@ -78,8 +80,7 @@
                <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"/>
@@ -95,8 +96,7 @@
                <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>
diff --git a/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.mqtt.espmilighthub/src/main/resources/OH-INF/update/instructions.xml
new file mode 100644 (file)
index 0000000..5c93553
--- /dev/null
@@ -0,0 +1,82 @@
+<?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>