]> git.basschouten.com Git - openhab-addons.git/blob
a33957479b19355e88b55c0f4938ca63a291157b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.mqtt.homeassistant.internal.component;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17
18 import java.math.BigDecimal;
19 import java.math.MathContext;
20 import java.util.Set;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.junit.jupiter.api.Test;
24 import org.openhab.binding.mqtt.generic.values.ColorValue;
25 import org.openhab.binding.mqtt.generic.values.OnOffValue;
26 import org.openhab.binding.mqtt.generic.values.PercentageValue;
27 import org.openhab.core.library.types.HSBType;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.PercentType;
30
31 /**
32  * Tests for {@link Light} conforming to the JSON schema
33  *
34  * @author Cody Cutrer - Initial contribution
35  */
36 @NonNullByDefault
37 public class JSONSchemaLightTests extends AbstractComponentTests {
38     public static final String CONFIG_TOPIC = "light/0x0000000000000000_light_zigbee2mqtt";
39
40     @Test
41     public void testRgb() throws InterruptedException {
42         // @formatter:off
43         var component = (Light) discoverComponent(configTopicToMqtt(CONFIG_TOPIC),
44                 "{ " +
45                         "  \"availability\": [ " +
46                         "    { " +
47                         "      \"topic\": \"zigbee2mqtt/bridge/state\" " +
48                         "    } " +
49                         "  ], " +
50                         "  \"device\": { " +
51                         "    \"identifiers\": [ " +
52                         "      \"zigbee2mqtt_0x0000000000000000\" " +
53                         "    ], " +
54                         "    \"manufacturer\": \"Lights inc\", " +
55                         "    \"model\": \"light v1\", " +
56                         "    \"name\": \"Light\", " +
57                         "    \"sw_version\": \"Zigbee2MQTT 1.18.2\" " +
58                         "  }, " +
59                         "  \"name\": \"light\", " +
60                         "  \"schema\": \"json\", " +
61                         "  \"state_topic\": \"zigbee2mqtt/light/state\", " +
62                         "  \"command_topic\": \"zigbee2mqtt/light/set/state\", " +
63                         "  \"brightness\": true, " +
64                         "  \"color_mode\": true, " +
65                         "  \"supported_color_modes\": [\"onoff\", \"brightness\", \"rgb\"]" +
66                         "}");
67         // @formatter:on
68
69         assertThat(component.channels.size(), is(1));
70         assertThat(component.getName(), is("light"));
71
72         assertChannel(component, Light.COLOR_CHANNEL_ID, "", "dummy", "Color", ColorValue.class);
73
74         publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"ON\" }");
75         assertState(component, Light.COLOR_CHANNEL_ID, HSBType.WHITE);
76         publishMessage("zigbee2mqtt/light/state", "{ \"color\": {\"r\": 10, \"g\": 20, \"b\": 30 } }");
77         assertState(component, Light.COLOR_CHANNEL_ID, HSBType.fromRGB(10, 20, 30));
78         publishMessage("zigbee2mqtt/light/state", "{ \"brightness\": 255 }");
79         assertState(component, Light.COLOR_CHANNEL_ID, new HSBType("210,66,100"));
80
81         sendCommand(component, Light.COLOR_CHANNEL_ID, HSBType.BLUE);
82         assertPublished("zigbee2mqtt/light/set/state",
83                 "{\"state\":\"ON\",\"brightness\":255,\"color\":{\"r\":0,\"g\":0,\"b\":255}}");
84
85         // OnOff commands should route to the correct topic
86         sendCommand(component, Light.COLOR_CHANNEL_ID, OnOffType.OFF);
87         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"OFF\"}");
88
89         sendCommand(component, Light.COLOR_CHANNEL_ID, OnOffType.ON);
90         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\"}");
91
92         sendCommand(component, Light.COLOR_CHANNEL_ID, new PercentType(50));
93         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\",\"brightness\":127}");
94     }
95
96     @Test
97     public void testBrightnessAndOnOff() throws InterruptedException {
98         // @formatter:off
99         var component = (Light) discoverComponent(configTopicToMqtt(CONFIG_TOPIC),
100                 "{ " +
101                         "  \"name\": \"light\", " +
102                         "  \"schema\": \"json\", " +
103                         "  \"state_topic\": \"zigbee2mqtt/light/state\", " +
104                         "  \"command_topic\": \"zigbee2mqtt/light/set/state\", " +
105                         "  \"brightness\": true" +
106                         "}");
107         // @formatter:on
108
109         assertThat(component.channels.size(), is(1));
110         assertThat(component.getName(), is("light"));
111
112         assertChannel(component, Light.BRIGHTNESS_CHANNEL_ID, "", "dummy", "Brightness", PercentageValue.class);
113
114         publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"ON\", \"brightness\": 128 }");
115         assertState(component, Light.BRIGHTNESS_CHANNEL_ID,
116                 new PercentType(new BigDecimal(128 * 100).divide(new BigDecimal(255), MathContext.DECIMAL128)));
117
118         sendCommand(component, Light.BRIGHTNESS_CHANNEL_ID, PercentType.HUNDRED);
119         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\",\"brightness\":255}");
120
121         sendCommand(component, Light.BRIGHTNESS_CHANNEL_ID, OnOffType.OFF);
122         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"OFF\"}");
123     }
124
125     @Test
126     public void testOnOffOnly() throws InterruptedException {
127         // @formatter:off
128         var component = (Light) discoverComponent(configTopicToMqtt(CONFIG_TOPIC),
129                 "{ " +
130                         "  \"name\": \"light\", " +
131                         "  \"schema\": \"json\", " +
132                         "  \"state_topic\": \"zigbee2mqtt/light/state\", " +
133                         "  \"command_topic\": \"zigbee2mqtt/light/set/state\"" +
134                         "}");
135         // @formatter:on
136
137         assertThat(component.channels.size(), is(1));
138         assertThat(component.getName(), is("light"));
139
140         assertChannel(component, Light.ON_OFF_CHANNEL_ID, "", "dummy", "On/Off State", OnOffValue.class);
141
142         publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"ON\" }");
143         assertState(component, Light.ON_OFF_CHANNEL_ID, OnOffType.ON);
144         publishMessage("zigbee2mqtt/light/state", "{ \"state\": \"OFF\" }");
145         assertState(component, Light.ON_OFF_CHANNEL_ID, OnOffType.OFF);
146
147         sendCommand(component, Light.ON_OFF_CHANNEL_ID, OnOffType.OFF);
148         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"OFF\"}");
149         sendCommand(component, Light.ON_OFF_CHANNEL_ID, OnOffType.ON);
150         assertPublished("zigbee2mqtt/light/set/state", "{\"state\":\"ON\"}");
151     }
152
153     @Override
154     protected Set<String> getConfigTopics() {
155         return Set.of(CONFIG_TOPIC);
156     }
157 }