]> git.basschouten.com Git - openhab-addons.git/commitdiff
[mqtt.homeassistant] Fix color lights that don't specify color_mode: true (#17240)
authorCody Cutrer <cody@cutrer.us>
Tue, 13 Aug 2024 21:22:31 +0000 (15:22 -0600)
committerGitHub <noreply@github.com>
Tue, 13 Aug 2024 21:22:31 +0000 (23:22 +0200)
* [mqtt.homeassistant] Fix color lights that don't specify color_mode: true

See https://github.com/home-assistant/core/pull/111676

Signed-off-by: Cody Cutrer <cody@cutrer.us>
bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLight.java
bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Light.java
bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/JSONSchemaLightTests.java

index ca016efd345d95b99dad88d316501b5bc932217d..4895e6cdccc58b729a54cc9a18eaa29bcb0d08e1 100644 (file)
@@ -22,7 +22,6 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
 import org.openhab.binding.mqtt.generic.values.TextValue;
 import org.openhab.binding.mqtt.homeassistant.internal.ComponentChannelType;
-import org.openhab.binding.mqtt.homeassistant.internal.exception.UnsupportedComponentException;
 import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.HSBType;
 import org.openhab.core.library.types.OnOffType;
@@ -82,19 +81,7 @@ public class JSONSchemaLight extends AbstractRawSchemaLight {
     @Override
     protected void buildChannels() {
         List<LightColorMode> supportedColorModes = channelConfiguration.supportedColorModes;
-        if (supportedColorModes != null && supportedColorModes.contains(LightColorMode.COLOR_MODE_COLOR_TEMP)) {
-            colorModeValue = new TextValue(
-                    supportedColorModes.stream().map(LightColorMode::serializedName).toArray(String[]::new));
-            buildChannel(COLOR_MODE_CHANNEL_ID, ComponentChannelType.STRING, colorModeValue, "Color Mode", this)
-                    .isAdvanced(true).build();
-        }
-
-        if (channelConfiguration.colorMode) {
-            if (supportedColorModes == null || channelConfiguration.supportedColorModes.isEmpty()) {
-                throw new UnsupportedComponentException("JSON schema light with color modes '" + getHaID()
-                        + "' does not define supported_color_modes!");
-            }
-
+        if (supportedColorModes != null) {
             if (LightColorMode.hasColorChannel(supportedColorModes)) {
                 hasColorChannel = true;
             }
@@ -103,6 +90,14 @@ public class JSONSchemaLight extends AbstractRawSchemaLight {
                 buildChannel(COLOR_TEMP_CHANNEL_ID, ComponentChannelType.NUMBER, colorTempValue, "Color Temperature",
                         this).commandTopic(DUMMY_TOPIC, true, 1)
                         .commandFilter(command -> handleColorTempCommand(command)).build();
+
+                if (hasColorChannel) {
+                    colorModeValue = new TextValue(
+                            supportedColorModes.stream().map(LightColorMode::serializedName).toArray(String[]::new));
+                    buildChannel(COLOR_MODE_CHANNEL_ID, ComponentChannelType.STRING, colorModeValue, "Color Mode", this)
+                            .isAdvanced(true).build();
+
+                }
             }
         }
 
index db6baee7ba164c45da96ce2ad04629f0cf42d0b6..b0de155f9052a2e6506813d29d4ed86463749b23 100644 (file)
@@ -83,8 +83,6 @@ public abstract class Light extends AbstractComponent<Light.ChannelConfiguration
         protected String schema = DEFAULT_SCHEMA;
         protected @Nullable Boolean optimistic; // All schemas
         protected boolean brightness = false; // JSON schema only
-        @SerializedName("color_mode")
-        protected boolean colorMode = false; // JSON schema only
         @SerializedName("supported_color_modes")
         protected @Nullable List<LightColorMode> supportedColorModes; // JSON schema only
         // Defines when on the payload_on is sent. Using last (the default) will send
index 6763883f1ef707bccc52679c0261dbe922d9ee12..43455b077f4594edecbf626ba7611bf234ea3b8a 100644 (file)
@@ -95,6 +95,63 @@ public class JSONSchemaLightTests extends AbstractComponentTests {
         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\",\"brightness\":127}");
     }
 
+    @Test
+    public void testRgbNewStyle() throws InterruptedException {
+        // @formatter:off
+        var component = (Light) discoverComponent(configTopicToMqtt(CONFIG_TOPIC),
+                """
+                { \
+                  "availability": [ \
+                    { \
+                      "topic": "zigbee2mqtt/bridge/state" \
+                    } \
+                  ], \
+                  "device": { \
+                    "identifiers": [ \
+                      "zigbee2mqtt_0x0000000000000000" \
+                    ], \
+                    "manufacturer": "Lights inc", \
+                    "model": "light v1", \
+                    "name": "Light", \
+                    "sw_version": "Zigbee2MQTT 1.18.2" \
+                  }, \
+                  "name": "light", \
+                  "schema": "json", \
+                  "state_topic": "zigbee2mqtt/light/state", \
+                  "command_topic": "zigbee2mqtt/light/set/state", \
+                  "brightness": true, \
+                  "supported_color_modes": ["rgb"]\
+                }\
+                """);
+        // @formatter:on
+
+        assertThat(component.channels.size(), is(1));
+        assertThat(component.getName(), is("light"));
+
+        assertChannel(component, Light.COLOR_CHANNEL_ID, "", "dummy", "Color", ColorValue.class);
+
+        publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"ON\" }");
+        assertState(component, Light.COLOR_CHANNEL_ID, HSBType.WHITE);
+        publishMessage("zigbee2mqtt/light/state", "{ \"color\": {\"r\": 10, \"g\": 20, \"b\": 30 } }");
+        assertState(component, Light.COLOR_CHANNEL_ID, HSBType.fromRGB(10, 20, 30));
+        publishMessage("zigbee2mqtt/light/state", "{ \"brightness\": 255 }");
+        assertState(component, Light.COLOR_CHANNEL_ID, new HSBType("210,67,100"));
+
+        sendCommand(component, Light.COLOR_CHANNEL_ID, HSBType.BLUE);
+        assertPublished("zigbee2mqtt/light/set/state",
+                "{\"state\":\"ON\",\"brightness\":255,\"color\":{\"r\":0,\"g\":0,\"b\":255}}");
+
+        // OnOff commands should route to the correct topic
+        sendCommand(component, Light.COLOR_CHANNEL_ID, OnOffType.OFF);
+        assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"OFF\"}");
+
+        sendCommand(component, Light.COLOR_CHANNEL_ID, OnOffType.ON);
+        assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\"}");
+
+        sendCommand(component, Light.COLOR_CHANNEL_ID, new PercentType(50));
+        assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\",\"brightness\":127}");
+    }
+
     @Test
     public void testBrightnessAndOnOff() throws InterruptedException {
         // @formatter:off